首先,让我说,我认为Tseng 的回答中有一些奇妙的观点,尤其是关于如何
- 伪造接口意味着永远不能调用“内部方法”,并且
- 你应该伪造依赖,而不是内部。如果您可以选择进行此更改,请立即执行并停止阅读我的答案。
如果您仍在阅读,我对两件事感到困惑:
- 应该
Test1
返回businessLogic
?正如它所写的那样(一旦编译错误被修复),我希望Test1
在返回 5 时返回 5(而不是 15)Test2
。
- 在
TestToTest
中,当您设置Returns(5)
on Test2
,然后调用Test1
时,由于您伪造了一个接口,我希望 sum 为 0,即 int 的默认值。我不知道你怎么会得到 5。事实上,我在这个测试中复制了这种行为:
[TestMethod]
public void TestToTestInterface()
{
//Arrange
var instance = A.Fake<IClassWithMethods>();
//Make calling Test2 return 5 and not 10.
A.CallTo(() => instance.Test2()).Returns(5);
//Call the method
var sum = instance.Test1();
//Assert if the business logic in the method works.
Assert.AreEqual(0, sum); // because Test1 wasn't faked
}
虽然我自己并不关心这种方法,但如果您真的想在 中包含可替换代码ClassWithMethods
,然后测试该Test1
方法,有一种方法:
- 我们需要制作
Test1
and Test2
virtual
,否则它们将无法伪造。
- 假的
ClassWithMethods
,不是IClasssWithMethods
。
- 告诉 fake 当
Test1
被调用时,它应该调用原始代码(这又会调用 fake Test2
)。
我已经将这些更改放在一起,这个测试对我来说通过了:
public class ClassWithMethods : IClassWithMethods
{
public virtual int Test1()
{
var value = this.Test2(); //Unittest should substitute with 5
var businesslogic = value + 10; //The business logic
return businesslogic;
}
public virtual int Test2()
{
return 10; //I try to mock this value away in the test. Don´t go here!
}
}
[TestMethod]
public void TestToTestClass()
{
//Arrange
var instance = A.Fake<ClassWithMethods>();
//Make calling Test2 return 5 and not 10.
A.CallTo(() => instance.Test2()).Returns(5);
// Make sure that Test1 on our fake calls the original ClassWithMethods.Test1
A.CallTo(() => instance.Test1()).CallsBaseMethod();
//Call the method
var sum = instance.Test1();
//Assert if the business logic in the method works.
Assert.AreEqual(15, sum);
}