Объект Moq не вызывает метод

#c# #moq

#c# #moq

Вопрос:

У меня есть класс, для которого я создал макет, чтобы я мог его протестировать.

Сам класс выглядит примерно так:

 public class MyData
{
    private string data;
    private string path;
    
     public MyData(string apath)
     {
        this.path = apath;
     }

    public virtual async Task<string> GetData()
    {
        if(IsDataExpired())
        {
            data = await CreateData();
        }
        return data;
    }

    protected virtual bool IsDataExpired() { ... }
    protected virtual async Task<string> CreateData() { ... }
}
 

И тест:

  public void TestData()
    {
        string data = "some data";
        Mock<MyData> dataMock = new Mock<MyData>("path");
               
        dataMock.Protected().Setup<bool>("IsDataExpired").Returns(true);
        dataMock.Protected().Setup<Task<string>>("CreateData").ReturnsAsync(data);
        var dataRes = dataMock.Object.GetData().Resu<
        Assert.IsNotNull(dataRes);
    }
 

Проблема в том, что по какой-то причине значение dataRes равно нулю в конце теста. Я попытался выполнить отладку внутри класса, но похоже, что код даже не вводит GetData метод и не достигает какой-либо точки останова, и данные немедленно получают нулевое значение.

Я неправильно вызываю метод? Почему он не вводит метод?

Ответ №1:

Почему он не вводит метод?

Moq virtual по умолчанию переопределяет члены.

Настройте макет для вызова базового виртуального члена, установив CallBase для свойства значение true

CallBase = true позволит макету вызывать реализацию (ы) базового класса, если ожидание (настройка) не переопределяет элемент.

Кроме того, поскольку тестируемый элемент является асинхронным, тест также должен быть асинхронным

 public async Task TestData() {
    //Arrange
    string data = "some data";
    Mock<MyData> dataMock = new Mock<MyData>("path") {
        CallBase = true
    };
           
    dataMock.Protected().Setup<bool>("IsDataExpired").Returns(true);
    dataMock.Protected().Setup<Task<string>>("CreateData").ReturnsAsync(data);

    //Act
    string dataRes = await dataMock.Object.GetData();

    //Assert
    Assert.IsNotNull(dataRes);
}