Net Framework Xunit с модульным тестированием Moq продолжает вызывать оригинальную функцию - PullRequest
1 голос
/ 23 марта 2020

У меня проблема с насмешкой, потому что она продолжает вызывать исходную функцию. Это мой демонстрационный код

Первый файл - это интерфейс, содержащий функцию, которую я хочу смоделировать.

public interface IDemoReplace
{
    int FunctionToBeReplaced();
}

Второй файл - это класс, который фактически имеет реализацию для функции

public class DemoReplace : IDemoReplace
{
    public int FunctionToBeReplaced()
    {
        //this function contains sql query in my real project
        return 1;
    }
}

Третий файл - это класс, который я хочу проверить

public class ClassToBeTested
{
    public int TestThisFunction()
    {
        IDemoReplace replace = new DemoReplace();
        var temp = replace.FunctionToBeReplaced();
        return temp;
    }
}

Последний файл - это класс теста

public class TestClass
{

    [Fact]
    public void TryTest()
    {
        using (var mock = AutoMock.GetLoose()) {
            //Arrange
            mock.Mock<IDemoReplace>()
                .Setup(x => x.FunctionToBeReplaced())
                .Returns(returnTwo());

            var classToBeTested = mock.Create<ClassToBeTested>();
            var expected = 2;

            //Act
            var actual = classToBeTested.TestThisFunction();

            //Assert
            Assert.Equal(expected, actual);
        }
    }

    public int returnTwo() {
        return 2;
    }
}

Этот тест не пройден с ожидаемым значением 2 и фактическое значение равно 1. Когда я пытался отладить, он не вызывает returnTwo, а вместо этого вызывает исходную функцию.

Я новичок в модульном тестировании, так что я пропустил? Пожалуйста, учтите, что приведенный выше код является лишь демонстрацией того, что произошло в моем реальном проекте. FunctionToBeReplaced на самом деле функция, которая выполняет и возвращает запись из базы данных, поэтому я хочу смоделировать эту функцию.

Спасибо:)

1 Ответ

1 голос
/ 23 марта 2020

Это проблема дизайна. Испытуемый объект тесно связан с проблемами реализации, которые затрудняют его изоляцию, чтобы он мог быть подвергнут модульному тестированию.

Он (субъект) вручную создает свою зависимость

IDemoReplace replace = new DemoReplace();

В идеале вы хотите явно ввести зависимости. Эти зависимости также должны быть абстракциями, а не конкрециями.

public class ClassToBeTested {
    private readonly IDemoReplace dependency;

    public ClassToBeTested(IDemoReplace dependency) {
        this.dependency = dependency;
    }

    public int TestThisFunction() {            ;
        var temp = dependency.FunctionToBeReplaced();
        return temp;
    }
}

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

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

public class TestClass {
    [Fact]
    public void TryTest() {
        using (var mock = AutoMock.GetLoose()) {
            //Arrange
            var expected = returnTwo();
            mock.Mock<IDemoReplace>()
                .Setup(x => x.FunctionToBeReplaced())
                .Returns(expected);

            var classToBeTested = mock.Create<ClassToBeTested>();

            //Act
            var actual = classToBeTested.TestThisFunction();

            //Assert
            Assert.Equal(expected, actual);
        }
    }

    public int returnTwo() {
        return 2;
    }
}
...