1

コード

だから私は2つのアセンブリを持っています

「AssemblyWithClassAndModuleInit」にはクラスが含まれています

public class MyBaseClass
{
}

「AssemblyWithInterfaceAndModuleInit」にはインターフェースが含まれています

public interface MyInterface
{
}

どちらにもモジュール初期化子が含まれています

public static class ModuleInitializer
{
    public static void Initialize()
    {
        Environment.SetEnvironmentVariable("ModuleInitializer", "true");
    }
}

「AssemblyWithClassAndModuleInit」のテスト (メモMyBaseClassは のベースとして使用されますClassTests)

[TestFixture]
public class ClassTests : MyBaseClass
{
    [Test]
    public void EnsureModuleInitIsCalled()
    {
        Assert.AreEqual("true", Environment.GetEnvironmentVariable("ModuleInitializer"));
    }
    [Test]
    public void EnsureAssemblyIsLoaded()
    {
        var assemblies = AppDomain.CurrentDomain.GetAssemblies();
        Assert.IsTrue(assemblies.Any(x => x.GetName().Name == "AssemblyWithClassAndModuleInit"));
    }
}

「AssemblyWithInterfaceAndModuleInit」のテスト ( 注MyInterfaceは のインターフェースとして使用されますInterfaceTests)

[TestFixture]
public class InterfaceTests : MyInterface
{
    [Test]
    public void EnsureModuleInitIsCalled()
    {
        Assert.AreEqual("true", Environment.GetEnvironmentVariable("ModuleInitializer"));
    }
    [Test]
    public void EnsureAssemblyIsLoaded()
    {
        var assemblies = AppDomain.CurrentDomain.GetAssemblies();
        Assert.IsTrue(assemblies.Any(x => x.GetName().Name == "AssemblyWithInterfaceAndModuleInit"));
    }
}

失敗する唯一のテストはInterfaceTests.EnsureModuleInitIsCalled.

質問

では、これはなぜですか?InterfaceTests実装MyInterfaceがモジュール初期化子を実行させるという事実はありませんか?

モジュール初期化子を挿入する方法

IL織りを使用しています。具体的にはhttps://github.com/Fody/ModuleInit

これを検知します

public static class ModuleInitializer
{
    public static void Initialize()
    {
        //Init code
    }
}

そして、これを追加します

static <Module>()
{
    ModuleInitializer.Initialize();
}

アップデート

  • 余談ですが、フィールドType interfaceType = typeof(MyInterface);を追加するとInterfaceTests、すべてのテストに合格します。
  • コーディングは .net 4.5 に対して行われました

完全なソース

これは単体テストの再現ですhttps://github.com/SimonCropp/Experiments/tree/master/ModuleInitRepro

4

1 に答える 1

0

明らかに関連する可能性があることの 1 つは、テスト クラスが prod アセンブリの基本クラスから派生していることです。したがって、テスト クラスのインスタンスを作成するには、基本クラスで (暗黙的に) コンストラクターを呼び出す必要があります。つまり、基本クラスを完全に読み込んで初期化する必要があるため、アセンブリを初期化する必要があります。

それをインターフェイスのバージョンと比較してください。インターフェイスを必要とすることは何もしていないため、テストクラスに prod-assembly インターフェイスを実装するという事実は、実行時には事実上無関係です。

あなたが持っていたなら、私はそれを疑う:

public void Foo(MyInterface x)
{
}

[Test]
public void EnsureAssemblyIsLoaded()
{
    Foo(this);
    ... assertions ...
}

その後、アセンブリを初期化できます。インターフェイスで宣言されたメソッドがあり、それらのメソッドのいずれかを から呼び出した場合Foo、アセンブリが初期化されることは間違いありません。

于 2013-03-29T18:18:25.480 に答える