Moq может только макетировать методы, которые являются виртуальными (или предоставлять имитационные реализации для интерфейсов).Если вы попробуете Setup
или Verify
для не виртуального члена, вы получите ошибку
Недопустимая проверка для не виртуального члена: m => m.TestMethod2 ()
В вашем случае вам потребуется изменить TestMethod2
на виртуальный, то есть
public virtual void TestMethod2()
, который затем можно протестировать:
var aMock = new Mock<A>();
aMock.Object.TestMethod();
aMock.Verify(m => m.TestMethod2(), Times.Once);
КакВы предложили проверить, вызывает ли класс внутренние методы для себя, это запах, указывающий на то, что вы либо
- проверяете детали внутренней реализации (например, если
TestMethod2()
был закрытым, это не нашдаже не знать об этом). - Или указание на то, что тестируемый класс / система нуждается в рефакторинге на несколько классов, которые должны быть слабо связаны, и, следовательно, могут быть изолированными и лучше тестируемыми.
Примечание
- Вы не можете
Verify
вызвать вызов, прежде чем вызовете метод на проверяемой системе, который вы хотите проверить, т.е.переместите Verify
после вызова .TestMethod()
, как я сделал. - Хотя вы можете изменитьваш код для использования
Setup
+ VerifyAll
подхода к тестированию, то есть обеспечения того, что все, что вы настроили, действительно вызывается:
aMock.Setup(m => m.TestMethod2());
aMock.Object.TestMethod();
aMock.VerifyAll();
Однако есть спорвокруг того, нарушает ли использование VerifyAll
принцип AAA
(поскольку вы также фактически указываете критерии Verify
в элементе Arrange
), и я также обнаружил, что этот подход делает невозможным рефакторинг иСУХОЙ макет настроек в крупномасштабных тестах, и вы также потеряете некоторые из более точного уровня проверки (например, Times.Once
).