Используя Moq, чтобы определить, вызван ли метод
Насколько я понимаю, я могу проверить, что вызов метода произойдет, если я вызову метод более высокого уровня, то есть:
public abstract class SomeClass()
{
public void SomeMehod()
{
SomeOtherMethod();
}
internal abstract void SomeOtherMethod();
}
Я хочу проверить, что если я вызову SomeMethod()
, то я ожидаю, что будет вызван SomeOtherMethod()
.
Я правильно понял, что такой тест доступен в насмешливой структуре?
Ответы
Ответ 1
Вы можете увидеть, вызван ли метод в том, что вы издевались, с помощью 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. Если он раскоментирован, он пройдет.
Ответ 2
Нет, макет тестирования предполагает, что вы используете определенные тестируемые шаблоны проектирования, одним из которых является инъекция. В вашем случае вы будете тестировать SomeClass.SomeMethod
и SomeOtherMethod
должны быть реализованы в другом объекте, который должен быть сопряжен.
Конструктор Someclass
будет выглядеть как New(ISomeOtherClass)
. Затем вы издеваетесь над ISomeOtherClass
и задаете ожидание на своем SomeOtherMethod
для вызова и проверки ожидания.
Ответ 3
Несмотря на то, что я согласен, что ответ @Paul - рекомендуемый путь, я просто хочу добавить один альтернативный путь, который обеспечивает moq
off the self.
Так как SomeClass
является abstract
это действительно насмешливо, но public void SomeMehod()
- нет. CallBase
том, чтобы найти способ CallBase
и каким-то образом вызвать этот метод, а затем с помощью 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);