如何从另一个函数中调用的函数模拟/解析结果?通常,Test2将是一个DataAccess方法,我不想获取实际数据。 我喜欢我测试的单元测试是业务逻辑。
这就是我现在所拥有的,但它根本不起作用。 Sum始终声明为5!
public int Test1()
{
var value = this.Test2(); //Unittest should substitute with 5
var businesslogic = value + 10; //The business logic
return businesslogic;
}
public int Test2()
{
return 10; //I try to mock this value away in the test. Don´t go here!
}
然后我有一个Unittest,我想在我的“业务逻辑”上运行。
[TestMethod()]
public void TestToTest()
{
//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(15, sum);
}
答案 0 :(得分:3)
据我所知,你不能这样做。
你的instance
不是真实类的实例,只是它界面上的一个模型,因此对instance.Test1()
的调用不会调用你上面描述的代码。但是你可以使用UnitTest Test2
方法。
然而,您可以做的是进行2次单元测试。
在第一个测试(测试方法Test2
)中,您使用必要的依赖项实例化您的类(或者如果没有与某些值/参数的依赖关系)。
然后使用相同的输入参数和Testing Test()
方法进行第二次测试。
模型仅用于必须在接口上进行模拟的依赖项(在您测试的类的实例化 之外)。即如果您有ClassA
且ClassB
和ClassA
取决于IClassB
接口。然后你可以模拟B来测试A.
答案 1 :(得分:3)
首先,我要说我认为Tseng's answer中存在很多奇点,特别是关于如何
如果你还在读书,我对两件事感到困惑:
Test1
返回businessLogic
吗?正如它的编写(一旦修复了编译错误),当Test1
返回5时,我希望Test2
返回5(而不是15)。TestToTest
中,当您在Returns(5)
上设置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
和Test2
virtual
,否则它们不会是假的。ClassWithMethods
,而不是IClasssWithMethods
。Test1
时,它应该调用原始代码(它将依次调用假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);
}