Я действительно ценю Moq Loose
насмешка поведения, которое возвращает значения по умолчанию, когда никакие ожидания не установлены. Это удобно и сохраняет меня код, и это также действует как меры по обеспечению безопасности: зависимости неумышленно не назовут во время модульного теста (как долго, поскольку они являются виртуальными).
Однако я смущен тем, как сохранить эти преимущества, когда метод под тестом, оказывается, является виртуальным.
В этом случае я действительно хочу назвать реальный код для того одного метода при тихом наличии остальной части класса, который свободно дразнят.
Все, что я нашел в своем поиске, - то, что я мог установить mock.CallBase = true
гарантировать, что метод называют. Однако это влияет на целый класс. Я не хочу делать это, потому что это помещает меня в дилемму обо всех других свойствах и методах в классе, которые скрывают зависимости от вызова: если CallBase верен затем, что я имею к также
То, что я думаю, что хочу, является чем-то как:
mock.Setup(m => m.VirtualMethod()).CallBase();
так, чтобы, когда я звоню mock.Object.VirtualMethod()
, Moq звонит в реальную реализацию...
Q: С Moq, там какой-либо способ протестировать виртуальный метод, когда я дразнил класс, чтобы заблокировать всего несколько зависимостей? Т.е. не обращаясь к CallBase=true и имея необходимость заблокировать все зависимости?
Пример кода для иллюстрирования
(использование MSTest, InternalsVisibleTo DynamicProxyGenAssembly2)
В следующем примере, TestNonVirtualMethod
передачи, но TestVirtualMethod
сбои - возвращают пустой указатель.
public class Foo
{
public string NonVirtualMethod() { return GetDependencyA(); }
public virtual string VirtualMethod() { return GetDependencyA();}
internal virtual string GetDependencyA() { return "! Hit REAL Dependency A !"; }
// [... Possibly many other dependencies ...]
internal virtual string GetDependencyN() { return "! Hit REAL Dependency N !"; }
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestNonVirtualMethod()
{
var mockFoo = new Mock<Foo>();
mockFoo.Setup(m => m.GetDependencyA()).Returns(expectedResultString);
string result = mockFoo.Object.NonVirtualMethod();
Assert.AreEqual(expectedResultString, result);
}
[TestMethod]
public void TestVirtualMethod() // Fails
{
var mockFoo = new Mock<Foo>();
mockFoo.Setup(m => m.GetDependencyA()).Returns(expectedResultString);
// (I don't want to setup GetDependencyB ... GetDependencyN here)
string result = mockFoo.Object.VirtualMethod();
Assert.AreEqual(expectedResultString, result);
}
string expectedResultString = "Hit mock dependency A - OK";
}