Как мне написать модульный тест для этого метода, который вызывается внутри al oop? - PullRequest
0 голосов
/ 13 июля 2020

Я пытаюсь протестировать метод с помощью xunit и moq. Тест "publi c void DoSomeWork_Verify_GetJsonDataString_is_called ()" завершился ошибкой. Пожалуйста, дайте мне знать, что мне не хватает в тесте / насмешке. GetJsonDataString - это вызов API, который возвращает строку json.

public class A {
    private readonly IData _data;
    private readonly IApiCall _apiCall;
       
    public A (IData data, IApiCall apiCall)
    {
        _data = data;
        _apiCall = apiCall;
    }
       
    public void DoSomeWork
    {
        var apps = _data.GetListOfApps(); // test on this method call is passing
        foreach(var app in apps)
        {
            if(string.IsNullOrEmpty(app.AppId)) continue;
            string jsonString = _apiCall.GetJsonDataString("ApiEndpoint" + app.AppId); // how do i test this method call? Note: I'm not using async, this is just a console app.
        }

       
    }

}

//MyTest
public class TestA
{
    private readonly Mock<IData> _data;
    private readonly Mock<IApiCall> _apicall;

    public TestA()
    {
        _data = new Mock<IData>;
        _apiCall = new Mock<IApiCall>;

    }

    public void DoSomeWork_Verify_GetListOfApps_is_called() 
    {
        _data.Setup(x => x.GetListOfApps());
        var sut = new A(_data.Object, _apiCall.Object);
        sut.DoSomeWork();
        _data.Verify(x => x.GetListOfApps(), Times.AtLeastOnce);  // this passes
    }


   public void DoSomeWork_Verify_GetJsonDataString_is_called()
    {
        _apicall.Setup(x => x.GetJsonDataString(It.IsAny<string>()));
        var sut = new A(_data.Object, _apiCall.Object);
        sut.DoSomeWork();
        _apicall.Verify(x => x.GetJsonDataString(It.IsAny<string>()), Times.AtLeastOnce);  // Failing
    }
    


} 

1 Ответ

1 голос
/ 13 июля 2020

Вам нужно издеваться над GetListOfApps, чтобы он действительно возвращал вам что-то на l oop. Для этого вам нужно использовать метод Returns.

Предполагая, что метод возвращает List<App>, ваша настройка может выглядеть следующим образом:

_data.Setup(x => x.GetListOfApps())
     .Returns(new List<App> { new App { AppId = "X" } });

Теперь ваш метод будет получить данные на l oop и будет вызван метод, который вы пытаетесь проверить.

Обратите внимание, что пока вы настраиваете GetJsonDataString, вы не передаете ему возвращаемое значение. По умолчанию Moq вернет null, но вам, вероятно, следует также имитировать это с возвращаемым значением.

_data.Setup(x => x.GetJsonDataString(It.IsAny<string>()))
     .Returns("some string");

Существуют также перегрузки Returns, которые принимают фабричную функцию и принимают аргументы, переданные в фиктивная функция в качестве входных данных. Вы можете использовать это, если хотите / хотите, чтобы результат возврата отличался в зависимости от входных параметров.

_data.Setup(x => x.GetJsonDataString(It.IsAny<string>()))
     .Returns(strParam => "some string" + strParam);

Теперь, когда вы проверяете, я бы не советовал использовать It.IsAny , когда вы можно . Иначе вы говорите, что вам все равно как это называется. Предположим, мы хотим проверить, что он действительно был вызван с использованием фиктивного значения сверху (AppId="X"), вы бы сделали это:

_apicall.Verify(x => x.GetJsonDataString("ApiEndPointX"), Times.Once);

Теперь у вас есть тест, который не просто проверяет, действительно ли метод был вызван, но на самом деле проверка была вызвана с ожидаемыми значениями.

Боковое примечание: у вашего тестового класса нет причин принимать параметры в своем конструкторе, особенно типа Mock<> . Вы их даже не используете! И технически это не должно даже выполняться, поскольку у вас нет настройки IClassFixture. Вы можете полностью избавиться от конструктора (и назначить поля напрямую) или просто удалить параметры:

public TestA()
{
    _data = new Mock<IData>();
    _apiCall = new Mock<IApiCall>();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...