我正在用NUnit框架编写一个单元测试用例来测试我们的代码。
代码引用了第三方库,如下所示:
class MyClass: BaseClass
{
public void override FunctionA()
{
var a = BaseFunctionB();
}
}
我们没有BaseClass
的源代码,但BaseFunctionB
是非虚拟的。
我试图
Setup(x=> x.BaseFunctionB()).Reteruns("my values");
但它不允许。
我只想测试FunctionA
中的MyClass
,我不在乎BasefunctionB
中是否正确。
在这种情况下如何测试?
---------------------------- 2018-01-03更新------------- --------------------
我对BaseClass
:
public abstract class BaseClass1//we dont have source code for this class
{
public int GetValue()
{
//do something here
return 1;//
}
public abstract int GenerateOutPut();
}
class abstract class BaseClass2: BaseClass1
{
public new virtual int GetValue()
{
return base.GetValue();
}
}
class MyClass1: BaseClass2
{
public override int GenerateOutPut()
{
var a = GetValue();
a += 1;
return a;
}
}
class MyClass2: BaseClass2
{
public override int GenerateOutPut()
{
var a = GetValue();
a -= 1;
return a;
}
}
// there are many MyClass
class MyClassN: BaseClass2
{
public override int GenerateOutPut()
{
var a = GetValue();
//different logic here.
return a;
}
}
我做了一个用于测试MyClass1
的课程,如下所示:
class TestClass1: MyClass1
{
public override int GetValue()
{
return 100;
}
}
测试用例如下:
public void TestFunction()
{
var test = new TestClass1();
var result = test.GetValue();
assert.AreEqual(101, result);
}
现在我必须创建许多看起来不太好的TestClas
。但在运行代码覆盖方面,我必须做到(我尝试使用模拟对象执行,报告中没有代码覆盖,我猜因为它创建代理并在代理上运行它,所以我创建相同的东西我自己来测试原始源代码)
我有更好的解决方案吗?
答案 0 :(得分:1)
创建第二个基类和新成员以封装第三方依赖项是一个好主意。它允许您覆盖派生类中的成员。一般来说,尽量避免嘲笑你不拥有的东西。而是将第三方依赖项封装在您控制的抽象背后,以便您可以灵活地模拟/存根/伪造任何所需的测试行为。
使用示例中的MyClass1
public class MyClass1 : BaseClass2 {
public override int GenerateOutPut() {
var a = GetValue();
a += 1;
return a;
}
}
可以进行以下测试以验证受试者的预期行为。注意Moq允许通过在模拟对象上设置CallBase = true
来调用基本成员。
[TestClass]
public class MyClass1_Test {
[TestMethod]
public void MyClass1_Should_Generate_Output() {
//Arrange
var expected = 0;
var mock = new Mock<MyClass1>() {
CallBase = true //<-- let mock call base members
};
mock.Setup(_ => _.GetValue()).Returns(expected); // <-- mocked behavior
var sut = mock.Object; //<-- subject under test.
//Act
var actual = sut.GenerateOutPut();
//Assert
actual.Should().Be(expected + 1);
}
}
这几乎就像你手动但现在通过模拟代理一样。