Как имитировать методы для возврата из них фиктивных данных в C#? - PullRequest
1 голос
/ 05 августа 2020

У меня есть класс, который я пытаюсь протестировать, написав какой-нибудь модульный тест в C#. Я также использую библиотеку Moq в своем модульном тесте для имитации.

Ниже приведены некоторые методы в моем классе, которые я хочу имитировать, чтобы они могли возвращать фиктивные данные, которые я хочу всегда возвращать.

public class DataManager
{

    public DataManager(ILoggingService loggingService, IConfiguration configuration)
    {
        // ...
    }

    // how to mock this to return dummy data?
    private DataHolder GetData()
    {
        //... return DataHolder object
    }

    // how to mock this to return dummy data?
    private IEnumerable<ProcessClient> GetClientValues(string value)
    {
        //... return IEnumerable<ProcessClient> object
    }

}

Вот как я это тестирую:

    private Mock<ClientUtility> utility;

    [SetUp]
    public void Setup()
    {
        utility = new Mock<ClientUtility>();
    }

    [Test]
    public void Test1()
    {

        // what should I do here so that "GetData" and "GetClientValues" return dummy data when I call below class constructor?
        
        var testName = "config1";
        var testContent = "{}";

        utility.Setup(x => x.Add(new DataStatus { Pin = "test" }, "data.com", "test")).Returns(Task.FromResult(true));
        var dataManager = new DataManager(loggingService.Object, configuration.Object);

        Assert.AreEqual(testContent, dataManager.GetStuff(testName)[0]);
    }

Вопрос:

Как я могу издеваться над "GetData" и " GetClientValues ​​»с использованием Moq или любой другой библиотеки для возврата фиктивных данных из этих двух методов? Возможно ли это сделать?

1 Ответ

0 голосов
/ 05 августа 2020

Думаю, вы можете использовать CallBase = true. Таким образом, ваш макет будет вести себя как настоящий класс.

var dataManager = new Mock<DataManager>(loggingService.Object, configuration.Object) { CallBase = true };

dataManager.Object.Method1();
dataManager.Object.Method2();

И вы можете имитировать некоторые методы, как вы это делаете с утилитой.

Поиск по «CallBase» на странице:

https://github.com/Moq/moq4/wiki/Quickstart

ОБНОВЛЕНИЕ Я сделал методы publi c для их вызова. И есть проблема, которую я не видел в прошлый раз. Вам необходимо создать «виртуальные» методы, если вы хотите изменить их поведение.

Вот пример кода. Как видите, GetClientValues() возвращает реальные данные, потому что мы вызываем реальную реализацию по умолчанию с помощью CallBase = true, а GetData() возвращает фиктивные данные, потому что мы имитировали его поведение.

public class DataManager
    {

        public DataManager(ILoggingService loggingService, IConfiguration configuration)
        {
            // ...
        }

        // how to mock this to return dummy data?
        public virtual DataHolder GetData()
        {
            return new DataHolder
            {
                Data = "RealData"
            };
        }

        // how to mock this to return dummy data?
        public IEnumerable<ProcessClient> GetClientValues(string value)
        {
            return new List<ProcessClient>
            {
                new ProcessClient
                {
                    Data = "RealData"
                }

            };
        }

    }

И тесты.

public class Tests
    {
        [SetUp]
        public void Setup()
        {
        }

        [Test]
        public void Test1()
        {
            var loggingService = new Mock<ILoggingService>();
            var config = new Mock<IConfiguration>();
            var dataManager = new Mock<DataManager>(loggingService.Object, config.Object){CallBase = true};
            dataManager.Setup(x => x.GetData()).Returns(new DataHolder { Data = "FakeData" });

            Assert.AreEqual("RealData", dataManager.Object.GetClientValues("test").First().Data);
            Assert.AreEqual("FakeData", dataManager.Object.GetData().Data);

        }
    }

Но в любом случае я думаю, что этот подход не годится для тестирования. Проблема с тестированием приватных методов. У нас есть несколько способов (например, Invoke()), но в целом «если вы хотите провести модульное тестирование частного метода, что-то может быть не так». Я хотел бы порекомендовать вам прочитать что-нибудь о дизайне тестов и написании тестируемого кода. О тестировании частных методов Как вы проводите модульное тестирование частных методов? .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...