单元测试代码,使用一个单独的AppDomain

问题描述 投票:0回答:1

我有一个使用一个AppDomain动态加载插件代码。我有一个名为PluginFinder做的工作专用的内部类。在生产环境中这一切工作,但我现在想写MS单元测试它,我收到一个错误说,大会也不会被发现。

需要明确的是,主类创建的AppDomain并运行PluginFinder它加载它与正确的接口发现的类。一旦类被加载,控制返回到默认的AppDomain。该PluginFinder加载过程中仅使用。

我使用下面的代码来创建环境:

            //  Create a domain to text for plugins
            AppDomain domain = AppDomain.CreateDomain("PluginLoader");

            //  Set PluginFinder to run in the new domain (assemblyName, typeName)
            (PluginFinder)domain.CreateInstanceAndUnwrap(
                typeof(PluginFinder).Assembly.FullName, typeof(PluginFinder).FullName);

PluginFinder使用默认的构造函数,是一个私人的内部类。我得到的例外是如下:

    ------ Exception ------
Error:  Could not load file or assembly 'MyClass, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
There was an error creating the Plugin Loader.
Could not load file or assembly 'MyClass, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

   at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Activator.CreateInstance(String assemblyString, String typeName, Boolean ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, Evidence securityInfo, StackCrawlMark& stackMark)
   at System.Activator.CreateInstance(String assemblyName, String typeName)
   at System.AppDomain.CreateInstance(String assemblyName, String typeName)
   at System.AppDomain.CreateInstanceAndUnwrap(String assemblyName, String typeName)
   at System.AppDomain.CreateInstanceAndUnwrap(String assemblyName, String typeName)
   at MyClass.loadPlugins() in C:\Code\...
---- End Exception ----

我发现this的解决方案,这表明NUnit的运行在多个应用程序域,这使得无插件不可能的AppDomain的测试。我使用的MS单元测试,但我怀疑,这可能是这里的情况也是如此。

**** 解决 ****

正如在下面的评论中提到的,我需要使用重载的构造函数。我修改我的代码(如下图所示),和它的工作。

// Set up the AppDomainSetup
var setup = new AppDomainSetup();
setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;

// Set up the Evidence
var baseEvidence = AppDomain.CurrentDomain.Evidence;

//  Create a domain to text for plugins
AppDomain domain = AppDomain.CreateDomain("PluginLoader", baseEvidence, setup);

//  Set PluginFinder to run in the new domain (assemblyName, typeName)
PluginFinder finder = (PluginFinder)domain.CreateInstanceAndUnwrap(
    typeof(PluginFinder).Assembly.FullName, typeof(PluginFinder).FullName);
c# visual-studio unit-testing visual-studio-2017 appdomain
1个回答
1
投票

我不太知道什么NUnit的是在这里做,但问题可能是新的AppDomain的基本目录是不是你所期望的。考虑使用父域的设置信息,或明确创建新时直接从当前域复制基地:

AppDomain.CreateDomain("PlugInLoader", null, AppDomain.CurrentDomain.SetupInformation);
© www.soinside.com 2019 - 2024. All rights reserved.