假设我有以下课程:
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()并且runMethod1为true时调用ChildMethod1()。是否可以使用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
}
答案 0 :(得分:5)
您还可以将期望/设置设置为可验证,并且不需要严格模拟:
//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中不起作用。有关如何执行此操作,请参阅this question至少4.0.10827
答案 1 :(得分:4)
我想出了如何做到这一点。您可以使用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();
}
答案 2 :(得分:1)
这有点像黑客,但如何创建一个使ChildMethod1和ChildMethod公开然后Moqing的TestBase的子类呢?
答案 3 :(得分:0)
看起来您正在测试行为而不是公共接口。如果是这样的话,你可能会看一下测试私人成员的建议。
“是否可以使用Moq创建TestBase的实现,调用BaseMethod()并验证是否在Moq实现上调用了ChildMethod?”
这有点可能。但是你会测试模拟对象,而不是真实对象。
两个可能引导你朝着正确方向前进的问题:
descendatn类是否返回与基类不同的值?如果是这样,你可以测试它并忽略implimentation细节(使重构更容易)。
后代类是否调用不同的方法或不同的依赖项?如果是这样,您可以检查依赖项。