Использование Moq для определения, вызывается ли метод - PullRequest
152 голосов
/ 07 декабря 2008

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

public abstract class SomeClass()
{    
    public void SomeMehod()
    {
        SomeOtherMethod();
    }

    internal abstract void SomeOtherMethod();
}

Я хочу проверить, что если я позвоню SomeMethod(), то я ожидаю, что будет вызван SomeOtherMethod().

Правильно ли я считаю, что такого рода тесты доступны в фальшивом фреймворке?

Ответы [ 3 ]

179 голосов
/ 07 декабря 2008

Вы можете увидеть, был ли вызван метод в чем-то, что вы смоделировали, с помощью Verify, например ::

static void Main(string[] args)
{
        Mock<ITest> mock = new Mock<ITest>();

        ClassBeingTested testedClass = new ClassBeingTested();
        testedClass.WorkMethod(mock.Object);

        mock.Verify(m => m.MethodToCheckIfCalled());
}

class ClassBeingTested
{
    public void WorkMethod(ITest test)
    {
        //test.MethodToCheckIfCalled();
    }
}

public interface ITest
{
    void MethodToCheckIfCalled();
}

Если в строке оставить комментарий, она вызовет исключение MockException при вызове Verify. Если он не прокомментирован, он пройдет.

6 голосов
/ 24 февраля 2011

Нет, фиктивное тестирование предполагает, что вы используете определенные тестируемые шаблоны проектирования, одним из которых является внедрение. В вашем случае вы будете тестировать SomeClass.SomeMethod и SomeOtherMethod должны быть реализованы в другом объекте, который должен быть сопряжен.

Ваш Someclass конструктор будет выглядеть как New(ISomeOtherClass). Затем вы бы высмеяли ISomeOtherClass и установили ожидание для его вызова SomeOtherMethod и проверили ожидание.

0 голосов
/ 17 апреля 2019

Несмотря на то, что я согласен с тем, что @ ответ Павла - рекомендуемый путь, я просто хочу добавить один альтернативный путь, который предоставляется moq от самого себя.

Поскольку SomeClass - это abstract, это действительно насмешливо, а public void SomeMehod() - нет. Смысл в том, чтобы найти способ смоделировать и каким-то образом вызвать этот метод, а затем с помощью CallBase передать вызов на SomeOtherMethod(). Это может звучать как взлом, но это просто по сути. Его можно использовать в том случае, если предложенный рефакторинг невозможен.

// This class is used only for test and purpose is make SomeMethod mockable
public abstract class DummyClass : SomeClass
{
    public virtual void DummyMethod() => base.SomeMethod();
}

Тогда вы можете настроить DummyMethod() для передачи вызова, установив флаг CallBase.

//Arrange
var mock = new Mock<DummyClass>();
mock.Setup(m => m.DummyMethod()).CallBase();

//Act
mock.Object.SomeMethod();

//Assert
mock.Verify(m => m.SomeOtherMethod(), Times.Once);
...