Проверка 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());
Другие вопросы по тегам