C# 验证使用Moq调用受保护的抽象方法
假设我有以下课程:C# 验证使用Moq调用受保护的抽象方法,c#,unit-testing,testing,moq,C#,Unit Testing,Testing,Moq,假设我有以下课程: public class TestBase { public bool runMethod1 { get; set; } public void BaseMethod() { if (runMethod1) ChildMethod1(); else ChildMethod2(); } protected abstract void ChildMethod1(); protected abstract vo
public class TestBase
{
public bool runMethod1 { get; set; }
public void BaseMethod()
{
if (runMethod1)
ChildMethod1();
else
ChildMethod2();
}
protected abstract void ChildMethod1();
protected abstract void ChildMethod2();
}
我也有课
public class ChildTest : TestBase
{
protected override void ChildMethod1()
{
//do something
}
protected override void ChildMethod2()
{
//do something completely different
}
}
我使用的是Moq,我想编写一个测试,在调用BaseMethod()时验证是否调用了ChildMethod1(),并且runMethod1是否为true。是否可以使用Moq创建TestBase的实现,调用BaseMethod(),并验证是否在Moq实现上调用了ChildMethod
[Test]
public BaseMethod_should_call_correct_child_method()
{
TestBase testBase;
//todo: get a mock of TestBase into testBase variable
testBase.runMethod1 = true;
testBase.BaseMethod();
//todo: verify that ChildMethod1() was called
}
看起来你是在测试行为,而不是公共界面。如果这是有意的,那么您可能可以查看关于测试私有成员的建议 是否可以使用Moq创建TestBase的实现,调用BaseMethod()并验证是否在Moq实现上调用了ChildMethod 这有点可能。但是接下来您将测试模拟对象,而不是真实对象 有两个问题可能会引导你走向正确的方向:
这是一个小技巧,但是创建一个TestBase的子类,使ChildMethod1和ChildMethod成为公共的,然后Moqing呢?我知道怎么做了。您可以使用Moq模拟受保护的方法,通过进行严格的模拟,您可以验证它们是否被调用。现在我可以测试基类,而无需创建任何子类
[Test]
public BaseMethod_should_call_correct_child_method()
{
//strict mocks will make sure all expectations are met
var testBaseMock = new Mock<TestBase>(MockBehavior.Strict);
//expect that ChildMethod1() will be called once. (it's protected)
testBaseMock.Protected().Expect("ChildMethod1")
.AtMostOnce();
var testBase = testBaseMock.Object;
testBase.runMethod1 = true;
testBase.BaseMethod();
//make sure the method was called
testBase.VerifyAll();
}
[测试]
public BaseMethod\u应该调用\u correct\u child\u method()
{
//严格的模拟将确保满足所有期望
var testBaseMock=newmock(MockBehavior.Strict);
//预计ChildMethod1()将被调用一次。(它受保护)
testBaseMock.Protected().Expect(“ChildMethod1”)
.AtMostOnce();
var testBase=testBaseMock.Object;
testBase.runMethod1=true;
testBase.BaseMethod();
//确保调用了该方法
testBase.VerifyAll();
}
您还可以将期望/设置设置为可验证,并且不需要严格的模拟:
//expect that ChildMethod1() will be called once. (it's protected)
testBaseMock.Protected().Expect("ChildMethod1")
.AtMostOnce()
.Verifiable();
...
//make sure the method was called
testBase.Verify();
编辑
此语法在当前版本的Moq中不起作用。请参阅,了解如何至少从4.0.10827开始执行此操作。此示例使您看起来像是在测试CLR,而不是您自己的代码。这就是你真正想要的吗?实际的代码更复杂。我根据对象的状态在子类中调用不同的方法。我只是想在这里写一个简单的例子,但我会更新它,以便有更多的东西要测试。