Проверка File.Delete был вызван с помощью Moq
Я новичок в модульном тестировании. Я пытаюсь проверить что-то очень простое:
[HttpPost]
public ActionResult EditProfile(ProfileViewModel model)
{
if (ModelState.IsValid)
{
// Retrieve current user
var userId = User.Identity.GetUserId();
var user = _dataRepository.GetUserById(userId);
//If it isn't the single-instance default picture, delete the current profile
// picture from the Profile_Pictures folder
if (!String.Equals(user.ProfilePictureUrl, _defaultPic))
System.IO.File.Delete(Server.MapPath(user.ProfilePictureUrl));
В этом разделе кода я создаю условие, в котором эта строка будет оцениваться как true:
if (!String.Equals(user.ProfilePictureUrl, _defaultPic))
Я хотел бы убедиться, что System.IO.File.Delete
называется.
Каков наилучший способ сделать это?
Нужно ли рефакторинг, оборачивая System.IO.File.Delete
вызвать в моем собственном классе, который реализует интерфейс, так что я могу издеваться над ним и проверить, что он был вызван?
Я использую Moq.
1 ответ
Нужно ли проводить рефакторинг, обернув вызов System.IO.File.Delete в моем собственном классе, который реализует интерфейс, чтобы я мог смоделировать его и убедиться, что он был вызван?
да
Инкапсулировать проблемы реализации
public interface IFileSystem {
void Delete(string path);
//...code removed for brevity
}
public class ServerFileSystemWrapper : IFileSystem {
public void Delete(string path) {
System.IO.File.Delete(Server.MapPath(path));
}
//...code removed for brevity
}
Который был бы явно введен в зависимости через конструктор и используется.
if (!String.Equals(user.ProfilePictureUrl, _defaultPic))
_fileSystem.Delete(user.ProfilePictureUrl); //IFileSystem.Delete(string path)
Теперь это позволит устанавливать макеты и проверять их по мере необходимости
//Arrange
var mockFile = new Mock<IFileSystem>();
var profilePictureUrl = "...";
//...code removed for brevity
var sut = new AccountController(mockFile.Object, ....);
//Act
var result = sut.EditProfile(model);
//Assert
result.Should().NotBeNull();
mockFile.Verify(_ => _.Delete(profilePictureUrl), Times.AtLeastOnce());