类初始化和继承
本文关键字:继承 初始化 | 更新日期: 2023-09-27 18:08:41
我有一个测试的基类,它由以下方式组成:
[TestClass]
public abstract class MyBaseTest
{
protected static string myField = "";
[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
// static field initialization
myField = "new value";
}
}
现在我尝试创建一个继承基测试的新测试,具有以下签名:
[TestClass]
public class MyTest : MyBaseTest
{
[TestMethod]
public void BaseMethod_ShouldHave_FieldInitialized()
{
Assert.IsTrue(myField == "new value");
}
}
ClassInitialize
从未被子测试调用…什么是真实和正确的方法在MsTest上使用继承的测试初始化?
不幸的是你不能这样做,因为ClassInitializeAttribute类不能被继承。
继承的属性可以被使用它的类的子类使用。由于ClassInitializeAttribute
不能被继承,当MyTest
类初始化时,不能调用MyBaseTest
类中的ClassInitialize
方法。
MyTest
中再次定义ClassInitialize
方法,并且只调用基方法,而不是重复代码。一个潜在的解决方法是用AssemblyInitializeAttribute
定义一个新类。显然,它有不同的作用域,但对我来说,它满足了我的需求(横切关注点,这恰好需要每个测试类和测试方法的完全相同的设置)
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MyTests
{
[TestClass]
public sealed class TestAssemblyInitialize
{
[AssemblyInitialize]
public static void Initialize(TestContext context)
{
...
}
}
}
ClassInitialize和ClassCleanup属性有一个参数:
[ClassInitialize(InheritanceBehavior.BeforeEachDerivedClass)]
public static void ClassInitialize(TestContext context)
{
// gets called once for each class derived from this class
// on initialization
}
[ClassCleanup(InheritanceBehavior.BeforeEachDerivedClass)]
public static void Cleanup()
{
// gets called once for each class derived from this class
// on cleanup
}
在基类上使用静态构造函数?按照设计,它只执行一次,并且没有像ClassInitializeAttribute那样对继承有奇怪的限制。
更新:添加锁以避免多线程问题…
我们知道,类中的每个[TestMethod]在运行时都会构造一个新的类实例。每次发生这种情况时都将调用基类的无参数构造函数。难道不能简单地在基类中创建一个静态变量,并在构造函数运行时进行测试吗?
这可以帮助您不要忘记将初始化代码放在子类中。
不确定这种方法是否有缺点…
一样:
public class TestBase
{
private static bool _isInitialized = false;
private object _locker = new object();
public TestBase()
{
lock (_locker)
{
if (!_isInitialized)
{
TestClassInitialize();
_isInitialized = true;
}
}
}
public void TestClassInitialize()
{
// Do one-time init stuff
}
}
public class SalesOrderTotals_Test : TestBase
{
[TestMethod]
public void TotalsCalulateWhenThereIsNoSalesTax()
{
}
[TestMethod]
public void TotalsCalulateWhenThereIsSalesTax()
{
}
}