私のテスト用の基本クラスは次のように構成されています:
[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 Class は継承できないため、この方法では実現できません。
継承された属性は、それを使用するクラスのサブクラスで使用できます。 ClassInitializeAttribute
は継承できないため、MyTest
クラスが初期化されると、ClassInitialize
クラスのMyBaseTest
メソッドを呼び出すことはできません。
別の方法で解決してみてください。あまり効率的ではない方法は、ClassInitialize
でMyTest
メソッドを再度定義し、コードを複製する代わりに基本メソッドを呼び出すことです。
潜在的な回避策は、代わりにAssemblyInitializeAttribute
を使用して新しいクラスを定義することです。それは明らかに異なるスコープを持っていますが、私にとってはそれが私のニーズを満たします(横断的な懸念、ちょうどすべてのテストクラスとテストメソッドにまったく同じ設定を必要とすることです)。
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MyTests
{
[TestClass]
public sealed class TestAssemblyInitialize
{
[AssemblyInitialize]
public static void Initialize(TestContext context)
{
...
}
}
}
クラスのすべての[TestMethod]が実行されると、クラスの新しいインスタンスが構築されることがわかります。これが発生するたびに、基本クラスのパラメーターなしのコンストラクターが呼び出されます。基本クラスで静的変数を作成し、コンストラクターの実行時にテストすることはできませんでしたか?
これにより、サブクラスに初期化コードを忘れずに配置できます。
このアプローチに欠点があるかどうかはわかりません...
そのようです:
public class TestBase
{
private static bool _isInitialized = false;
public TestBase()
{
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()
{
}
}
基本クラスで静的コンストラクターを使用しますか?設計により一度だけ実行され、ClassInitializeAttributeのような継承に関する奇妙な制限はありません。