3

実行時にアセンブリをロードして、依存関係で「ローカルにコピー」せずに単体テストを実行することは可能ですか?

詳細:

私の .net ソリューションは次のようになります。

  • MainProject (exe) [「Class1Project」に依存し、「AssemblyLoaderProject」を使用して実行時にロードします]。

    「Class1Project」を「copy local = false」に設定し、「AssemblyLoaderProject」を「copy local = true」に設定

  • Class1Project (dll)

  • AssemblyLoaderProject (AppDomain.CurrentDomain.AssemblyResolve および Assembly.LoadFrom を使用して、実行時に依存関係アセンブリを読み込んで解決します)

  • UnitTestsProject (Nunit または MSTest のいずれか)

単体テスト プロジェクトで「Class1Project」をテストしようとしていますが、その構成を MainProject と同じに設定したいと考えています。

つまり、UnitTestProject は、'Class1Project' を 'copy local = false' で参照し、'AssemblyLoaderProject' を 'copy local = true' で参照し、それを使用して実行時にアセンブリをロードします。

しかし、何らかの理由で単体テストを実行できませんでした。ランナーは、「Class1Project」アセンブリを解決できなかったことを示す FileNotFoundException をスローします。

それをデバッグしようとすると、テスト ランナーが AssemblyLoaderProject にアセンブリをロードするように指示するコードに到達していないことがわかります。

テスト コードは次のようになります。

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        Loader.LoadAssemblies();
        Class1 cls = new Class1();
        Assert.IsTrue(true);
    }
}

これは、MSTest で VS2012 テスト ランナーを使用してデバッグしようとしたときに表示されるエラー メッセージです。

Test Name:  TestMethod1
Test FullName:  UnitTestProject1.UnitTest1.TestMethod1
Test Source:    c:\Users\user\Documents\Visual Studio 2012\Projects\ClassLibrary1\UnitTestProject1\UnitTest1.cs : line 13
Test Outcome:   Failed
Test Duration:  0:00:00.1177608

Result Message: 
Test method UnitTestProject1.UnitTest1.TestMethod1 threw exception: 
System.IO.FileNotFoundException: Could not load file or assembly 'ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.=== Pre-bind state information ===
LOG: User = \user
LOG: DisplayName = ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
 (Fully-specified)
LOG: Appbase = file:///C:/Users/user/Documents/Visual Studio 2012/Projects/ClassLibrary1/UnitTestProject1/bin/Debug
LOG: Initial PrivatePath = NULL
Calling assembly : UnitTestProject1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO 11.0\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\TESTWINDOW\vstest.executionengine.x86.exe.Config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Users/user/Documents/Visual Studio 2012/Projects/ClassLibrary1/UnitTestProject1/bin/Debug/ClassLibrary1.DLL.
LOG: Attempting download of new URL file:///C:/Users/user/Documents/Visual Studio 2012/Projects/ClassLibrary1/UnitTestProject1/bin/Debug/ClassLibrary1/ClassLibrary1.DLL.
LOG: Attempting download of new URL file:///C:/Users/user/Documents/Visual Studio 2012/Projects/ClassLibrary1/UnitTestProject1/bin/Debug/ClassLibrary1.EXE.
LOG: Attempting download of new URL file:///C:/Users/user/Documents/Visual Studio 2012/Projects/ClassLibrary1/UnitTestProject1/bin/Debug/ClassLibrary1/ClassLibrary1.EXE.
Result StackTrace:  at UnitTestProject1.UnitTest1.TestMethod1()
4

4 に答える 4

3

Loader.LoadAssembliesがイベントにサインアップするメソッドであると仮定すると、ランタイムがプロービングを介してAssemblyResolve見つけることができないため、この例外を受け取ります。ClassLibrary1.dllここでプロービングが機能する理由を理解することが重要です。Loader.LoadAssembliesメソッドを介してアセンブリをロードする前に、Jittedする必要があるため、プロービングが呼び出されます。適切に調整するには、ランタイムがコンパイル時に参照される型のアセンブリをロードする必要があります。'copy local'をfalseに設定したため、ファイルClassLibrary1.dllはコピーされず、プローブパスにありません。したがって、あなたのFileNotFoundException

まず、各テストの前に実行する属性でLoader.LoadAssembliesマークされたメソッドに移動してみます。TestInitializeただし、テスト実行前にファイルがコピーされる場所によっては、これも機能しない場合があります。テスト設定で展開を有効にして、DeploymentItem属性を使用する必要がある場合があります。

より大きな質問は、単体テストを行っている場合、依存関係に対して「ローカルコピー」をtrueに設定して、テストアセンブリとともにコピーできないのはなぜですか?

正確に何をするかに応じてLoader.LoadAssemblies、アセンブリが複数または異なるロードコンテキストにロードされることによって引き起こされる他の問題が発生する可能性があります。InvalidCastExceptionこれにより、タイプ「X」をタイプ「X」にキャストできないというエラーが表示されるなどの問題が発生する可能性があります。ただし、プロービングでアセンブリが見つからない場合は、AppDomain.AssemblyResolveが呼び出されてアセンブリをLoadコンテキストにロードするため、安全な場合があります。

于 2013-01-08T05:26:46.460 に答える
0

VS2012テストランナーにバグがあります。私のプロジェクトでは、すべての依存関係をcopy local = trueに設定していますが、「Out」フォルダーにコピーされないdllがまだいくつかあり、テストが失敗します。VS2010で同じテストを実行すると、すべてが完全に実行されます。

DeploymentAttributeを使用することは役に立ちますが、必須ではありません。

于 2013-01-31T16:44:30.377 に答える
0

DLL'Class1Project' をローダーで使用できるようにする必要があるため、プロジェクトを常にコピーするように設定したくない場合は、DeploymenItem属性を使用してテスト用にコピーすることができます。それを見つけることができます。

于 2013-01-08T01:05:44.570 に答える