2013-01-08 2 views
2

종속성에 '로컬 복사'없이 단위 테스트를 실행하고 런타임에 어셈블리를로드 할 수 있습니까?런타임에 종속 어셈블리를로드 할 때 단위 테스트를 실행할 수 있습니까?

자세한 내용 :

내 .NET 솔루션은 다음과 같습니다

  • MainProject (EXE)는 [ 'Class1Project'에 따라 달라집니다 'AssemblyLoaderProject'를 사용하여 런타임에로드]. 런타임

    에 'Class1Project'집합 '로컬 복사 = 거짓'및 행 'AssemblyLoaderProject'집합 '복사 진정한 = 로컬'

  • Class1Project (DLL)

  • AssemblyLoaderProject (부하 해결 종속성 어셈블리 AppDomain.CurrentDomain.AssemblyResolve 및 Assembly.LoadFrom있는)

  • UnitTestsProject (NUNIT 있거나 MSTEST)

를 사용

유닛 테스트 프로젝트에서 'Class1Project'를 테스트하려고하는데 MainProject와 동일한 설정을하고 싶습니다.

의미, UnitTestProject 또한 'copy local = false'및 'AssemblyLoaderProject'와 'copy local = true'를 사용하여 'Class1Project'를 참조하고이를 런타임에 어셈블리를로드하는 데 사용합니다.

하지만 단위 테스트를 실행할 수 없기 때문에 주자는 '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() 

답변

2

이벤트에 등록하는 것으로 가정하면 런타임에서 프로빙을 통해 ClassLibrary1.dll을 찾을 수 없으므로이 예외가 발생합니다. 여기서 왜 프로빙이 작동하는지 이해하는 것이 중요합니다. Loader.LoadAssemblies을 통해 어셈블리를로드하기 전에 메서드가 Jitted되어야하므로 탐색이 호출됩니다. 제대로 컴파일되기 위해서는 컴파일 타임에 참조되는 유형의 어셈블리를 런타임에서로드해야합니다. 'copy local'을 false로 설정 했으므로 ClassLibrary1.dll 파일은 복사되지 않고 프로빙 경로에 복사되지 않습니다. 따라서 FileNotFoundException입니다.

먼저 각 테스트 전에 TestInitialize 속성으로 표시된 메소드로 Loader.LoadAssemblies을 이동해보십시오.그러나 테스트 실행 전에 파일을 복사 할 위치에 따라이 작동하지 않을 수도 있습니다. 테스트 설정에서 배포를 활성화하고 DeploymentItem 특성을 사용해야 할 수 있습니다.

더 큰 질문은 : 단위 테스트의 경우 종속성에 대해 'copy local'을 true로 설정하여 테스트 어셈블리와 함께 복사하지 못하는 이유는 무엇입니까?

정확히 Loader.LoadAssemblies의 내용에 따라 어셈블리가 여러로드 컨텍스트 또는 다른로드 컨텍스트에로드되어 발생하는 다른 문제가 발생할 수 있습니다. 이로 인해 InvalidCastException 같은 오류가 발생하여 'X'유형을 'X'유형으로 변환 할 수 없다는 오류가 발생할 수 있습니다. 그러나 AppDomain.AssemblyResolve가 호출을 통해 어셈블리를로드 컨텍스트에로드 할 수 없으므로 AppDomain.AssemblyResolve가 호출되므로 안전 할 수 있습니다.

+0

이 경우 TestInitialize 메서드에서 'Loader.LoadAssemblies'를 호출했습니다. 로더는 전체 경로를 사용하여 class1 프로젝트를로드하므로 로컬 복사 또는 배포를 사용할 필요가 없습니다. 내 테스트 프로젝트에 Class1 (Class1Project에 상주하는)에서 파생 된 클래스가 들어있는 상황을 해결할 수 있습니까? 이 경우 테스트 러너에서 어셈블리를로드하려고하면 jit 및 프로빙 단계가 발생하고 실패합니다. – avivr

+0

기본 .exe 어셈블리에서 동일한 작업을 수행하고 Class1에서 파생 된 클래스를 만들면 응용 프로그램이 정상적으로 실행됩니다. 첫 번째 (Lodaer 실행 후 발생)에 액세스 할 때만 파생 클래스를 JIT하려고하며 테스트 컨텍스트에서 파일을로드 할 때 테스트 러너가 모든 어셈블리 유형을 JIT하려고합니까? 아마도 어떤 것이 테스트를 포함하고 있는지 파싱하는 것일까? – avivr

+0

@avivr 나는 네가 정확하다고 믿는다. 테스트 프레임 워크는 테스트 프로젝트에서 모든 유형을로드하여 테스트를 찾습니다. 이것은'TestInitialize' 이전에 발생하기 때문에 프로빙이 일어나기 전에'LoadAssemblies'가 실행되지 않고 동일한 예외가 발생합니다. –

0

당신은 있는지 확인해야하는 DLL'Class1Project '는 로더에서 사용할 수 있으므로 프로젝트를 항상 복사하도록 설정하지 않으려면 DeploymenItem 속성을 사용하여 테스트 용으로 복사하여로드에서 찾을 수 있도록합니다.

+0

로더는 Assembly.LoadFrom (FULL_PATH_TO_Class1ProjectDll)을 사용하므로 파일을 복사하지 않아도 어디서나 사용할 수 있어야합니다. – avivr

0

There is a bug in VS2012 test runner. 내 프로젝트에서 필자는 모든 종속성을 local = true를 복사하도록 설정했으며 "Out"폴더에 복사되지 않는 일부 DLL이있어 테스트가 실패합니다. VS2010에서 동일한 테스트를 실행하면 모든 것이 완벽하게 실행됩니다.

DeploymentAttribute를 사용하면 도움이되지만 필수는 아닙니다.

관련 문제