在 NUnit 测试中创建应用程序域的异常

Posted

技术标签:

【中文标题】在 NUnit 测试中创建应用程序域的异常【英文标题】:Exception creating an App Domain in NUnit test 【发布时间】:2014-06-23 12:44:41 【问题描述】:

我编写了一个插件库,可以在目录中搜索导出给定接口实现的程序集。它通过将所有程序集加载到仅反射上下文中的临时应用程序域并搜索导出的类型来实现此目的。然后卸载临时应用程序域,感兴趣的程序集加载到默认应用程序域中,然后实例化找到的类型的对象以通过搜索接口使用。

我正在尝试使用 NUnit 为该流程编写一些单元测试,但在尝试连接 ReflectionOnlyAssemblyResolve 事件时,我仅在单元测试中收到 FileNotFoundException。这是一个简单的例子:

using System;
using System.Reflection;
using NUnit.Framework;

namespace NUnitAppDomains

    [TestFixture]
    public class TestClass
    
        [Test]
        public void NUnitTest()
        
            var ad = AppDomain.CreateDomain("someName");

            // this next line throws a FileNotFoundException, complaining about not being 
            // able to find the test assembly itself... o.O
            ad.ReflectionOnlyAssemblyResolve += SomeHandler;

            AppDomain.Unload(ad);
        

        static Assembly SomeHandler(object sender, ResolveEventArgs args)
        
            // some code would be here

            throw new NotImplementedException();
        
    

我试图在已知位置的一些虚拟程序集上测试代码,其中一些包含/不包含有效的实施/s。我的代码是否不适合单元测试,或者如果是,我该如何避免这些异常?谢谢

【问题讨论】:

格式良好的问题,感谢SSCCE。欢迎来到 SO! 【参考方案1】:

问题在于您的代码在不同的应用程序库(NUnit 或 Visual Studio 或任何运行您的测试的程序)中运行。当您创建域而不指定基础时,它使用运行代码的应用程序的基础,例如“Program Files\NUnit\Bin”,当然也找不到你的程序集。

解决方法是在创建AppDomain时使用你代码的应用程序库,可以从当前线程获取:

var callingDomain = Thread.GetDomain();
var setup = new AppDomainSetup 
             
                ApplicationBase = callingDomain.SetupInformation.ApplicationBase 
            ;

var ad = AppDomain.CreateDomain("someName", null, setup);

This blog post 更详细一点,但不多。不过还是值得一读。

【讨论】:

完美,谢谢。我最初想象我可能需要一个 IAppDomainFactory 来实现单元测试,而我的原始代码用于生产实现,但似乎这两者都适合,因为它只是使搜索目录显式? 嗯,这是一个权衡。拥有NUnitAppDomainFactory 可能更具体一点,但当然会增加一点复杂性。如果您确实将其用于两者,我会在代码中留下一个很大的注释,说明为什么要这样做。

以上是关于在 NUnit 测试中创建应用程序域的异常的主要内容,如果未能解决你的问题,请参考以下文章

对 NUnit 测试使用 RunImpersonated 进行 HttpClient 调用失败,但在控制台中有效

NUnit - 读写文件的程序集

通过 NUnit 运行 C++ 代码

Visual Studio FsUnit测试设置 - 异常NUnit.Engine.NUnitEngineException

app.config 在哪里

如何在DHCP服务器中创建IP地址作用域