从测试类调用被测试类的非默认构造函数
本文关键字:测试类 默认 构造函数 调用 | 更新日期: 2023-09-27 18:17:31
我是单元测试的新手,我想知道这是如何解决的,我猜典型的问题:
我有一个保护方法,我想测试一下。我已经用测试类覆盖了测试类,但是测试类有带有4个参数的构造函数,没有默认构造函数。在测试类的哪个部分添加对基(4个参数)构造函数的调用?我尝试过[SetUp]
方法,但我得到Use of keyword 'base' is not valid in this context
错误。
我认为这个简单的例子是不言自明的,但这里有一个例子:
public class A
{
protected Class1 obj1;
protected Class2 obj2;
protected Class3 obj3;
protected Class4 obj4;
public A(Class1 obj1, Class2 obj2, Class3 obj3, Class4 obj4)
{
this.obj1 = obj1;
this.obj2 = obj2;
this.obj3 = obj3;
this.obj4 = obj4;
}
protected virtual void MethodA()
{
//some logic
}
}
[TestFixture]
public class ATests : A
{
[SetUp]
public void SetUp()
{
this.obj1 = Substitute.For<Class1>();
this.obj2 = Substitute.For<Class2>();
this.obj3 = Substitute.For<Class3>();
this.obj4 = Substitute.For<Class4>();
//this line below doesn't compile with the `Use of keyword 'base' is not valid in this context` error.
base(obj1, obj2, obj3, obj4);
}
[Test]
public void MethodA_test()
{
//test MethodA logic
}
}
ATests
不应该继承A
只需将测试类定义更改为
[TestFixture]
public class ATests
{
,而不是
base(obj1, obj2, obj3, obj4);
做一些类似
的事情this.globalA = new A(obj1, obj2, obj3, obj4);
其中globalA
是A
类型的私有字段,您可以在测试中使用。
要访问protected
方法,您可以将您的测试项目作为朋友程序集添加到您的主项目中,并将您的protected
方法标记为protected internal
。
常见且简单的方法是创建从A派生的类,它将暴露您想要测试的受保护成员:
public class TestableA : A
{
public void TestableMethodA()
{
base.MethodA();
}
}
现在,您的测试装置将执行TestableA
。您实际上并不从A中派生测试fixture,您只是在测试中使用新的派生的、仅用于测试的类:
[TestFixture]
public void ATests
{
[Test]
public void MethodA_DoesSomethingImportant()
{
var testedComponent = new TestableA();
testedComponent.TestableMethodA();
// verify
}
}
这种方法的缺点是需要为测试目的创建额外的类型。这可以通过使用模拟框架(以及使用模拟调用基实现)来缓解。当其他所有方法都失败或最终代价太大时,为了单元测试的目的而改变方法的可见性应该是最后的手段。