Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# VisualStudio NUnit3TestAdapter与第三方DLL的测试项目_C#_Visual Studio_Nunit 3.0 - Fatal编程技术网

C# VisualStudio NUnit3TestAdapter与第三方DLL的测试项目

C# VisualStudio NUnit3TestAdapter与第三方DLL的测试项目,c#,visual-studio,nunit-3.0,C#,Visual Studio,Nunit 3.0,我有一个测试项目Proj_Test,有两个nuget包 <packages> <package id="NUnit" version="3.6.0" targetFramework="net45" /> <package id="NUnit3TestAdapter" version="3.6.0" targetFramework="net45" /> </packages> 设置似乎被忽略 如何管理测试的这些依赖关系 编辑: 我想我是怎么

我有一个测试项目
Proj_Test
,有两个nuget包

<packages>
  <package id="NUnit" version="3.6.0" targetFramework="net45" />
  <package id="NUnit3TestAdapter" version="3.6.0" targetFramework="net45" />
</packages>
设置似乎被忽略

如何管理测试的这些依赖关系

编辑: 我想我是怎么了

专用程序集部署在与应用程序相同的目录结构中。如果为PrivateBinPath指定的目录不在ApplicationBase下,则将忽略它们


创建副本真的是唯一的解决方案吗?

如果找不到更好的解决方案,请尝试自己解决

using ConsoleApplication6;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Reflection;

namespace UnitTestProject1
{
    [TestClass]
    public class UnitTest1
    {
        [TestInitialize]
        public void Init()
        {
           AppDomain currentDomain = AppDomain.CurrentDomain;
           currentDomain.AssemblyResolve += MyResolveEventHandler;
        }

        [TestMethod]
        public void TestMethod1() { Assert.AreEqual(new MyClass().DoSomething(), 1); }

        [TestMethod]
        public void TestMethod2() { Assert.AreEqual(new MyClass().DoSomething(), 1); }

        private Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
        {
            return Assembly.LoadFile(@"C:\MyPath\MyAssembly.dll");
        }
    }
}

不幸的是,程序集探测只能在子目录上工作,所以您不能使用它…

多亏了George Vos的回答,这就是我最终实现的

using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;

//https://github.com/nunit/docs/wiki/SetUpFixture-Attribute
//A SetUpFixture outside of any namespace provides SetUp and TearDown for the entire assembly.

[SetUpFixture]
class GlobalSetup
{

    [DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern int SetDllDirectory(string NewDirectory);

    static HashSet<string> directories = new HashSet<string>
    {
        @"D:\Drive\AnyThirdParty\"
    };

    [OneTimeSetUp]
    public void RunBeforeAnyTests()
    {
        AddManagedHandler();
        SetNativeDirectories();
    }

    private void SetNativeDirectories()
    {
        if(directories.Count() != 1)
        {
            //TODO: add support for multiple directories
            throw new NotImplementedException("current implementation only supports exactly one directory");
        }

        if (0 == SetDllDirectory(directories.First()))
        {
            throw new Exception("SetDllDirectory failed with error " + Marshal.GetLastWin32Error());
        }
    }

    private void AddManagedHandler()
    {
        AppDomain currentDomain = AppDomain.CurrentDomain;
        currentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
    }

    private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        IEnumerable<string> candidates = FindCandidates(new AssemblyName(args.Name));
        return Assembly.LoadFrom(candidates.First());
    }

    private static IEnumerable<string> FindCandidates(AssemblyName assemblyname)
    {
        List<string> candidates = new List<string>();
        foreach (var path in directories)
        {
            string candidate = string.Format(@"{0}{1}.dll", path, assemblyname.Name);
            if (File.Exists(candidate))
            {
                candidates.Add(candidate);
            }
        }
        if (!candidates.Any())
        {
            throw new FileNotFoundException(string.Format("Can not find assembly: '{0}.dll'", assemblyname.Name));
        }
        return candidates;
    }
}
使用NUnit.Framework;
使用制度;
使用System.Collections.Generic;
使用System.IO;
使用System.Linq;
运用系统反思;
使用System.Runtime.InteropServices;
使用系统文本;
//https://github.com/nunit/docs/wiki/SetUpFixture-Attribute
//任何命名空间之外的SetUpFixture为整个程序集提供设置和拆卸。
[固定装置]
类全局设置
{
[DllImport(“kernel32”,CharSet=CharSet.Unicode,SetLastError=true)]
私有静态外部int SetDllDirectory(字符串NewDirectory);
静态哈希集目录=新哈希集
{
@“D:\Drive\AnyThirdParty\”
};
[一次性设置]
public void RunBeforeAnyTests()
{
AddManagedHandler();
SetNativeDirectories();
}
私有无效SetNativeDirectories()
{
if(directories.Count()!=1)
{
//TODO:添加对多个目录的支持
抛出新的NotImplementedException(“当前实现仅支持一个目录”);
}
if(0==SetDllDirectory(directories.First())
{
抛出新异常(“SetDllDirectory失败,错误为”+Marshal.GetLastWin32Error());
}
}
私有void AddManagedHandler()
{
AppDomain currentDomain=AppDomain.currentDomain;
currentDomain.AssemblyResolve+=currentDomain_AssemblyResolve;
}
私有程序集CurrentDomain_AssemblyResolve(对象发送方,ResolveEventArgs args args)
{
IEnumerable candidates=FindCandidates(新的AssemblyName(args.Name));
返回Assembly.LoadFrom(candidates.First());
}
私有静态IEnumerable FindCandidates(AssemblyName AssemblyName)
{
列表候选者=新列表();
foreach(目录中的var路径)
{
stringcandidate=string.Format(@“{0}{1}.dll”,路径,assemblyname.Name);
如果(文件存在(候选))
{
候选人。添加(候选人);
}
}
如果(!candidates.Any())
{
抛出新的FileNotFoundException(string.Format(“找不到程序集:{0}.dll',assemblyname.Name));
}
返回候选人;
}
}

我查看了“AssemblyResolve”,似乎您需要按方法分离调用。因此,我在“OneTimeSetUp”中尝试了它,但没有触发事件-我可能遗漏了什么?@Johannes我想不出原因。我回家后会尝试。我认为我的依赖项之一是本机dll。这可能与此有关。@Johannes我看不出TestInitialize有问题……请尝试在MyResolveEventHandler中添加断点和Try/catch,并检查未能加载的程序集(请参见args.Name)还有whyok-在我的最小示例中,我注意到a)您的代码适用于托管程序集,b)我需要为本机DLL设置路径。使用函数AddDllDirectories并不简单,因此为了兼容性,我使用SetDllDirectories。
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;

//https://github.com/nunit/docs/wiki/SetUpFixture-Attribute
//A SetUpFixture outside of any namespace provides SetUp and TearDown for the entire assembly.

[SetUpFixture]
class GlobalSetup
{

    [DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern int SetDllDirectory(string NewDirectory);

    static HashSet<string> directories = new HashSet<string>
    {
        @"D:\Drive\AnyThirdParty\"
    };

    [OneTimeSetUp]
    public void RunBeforeAnyTests()
    {
        AddManagedHandler();
        SetNativeDirectories();
    }

    private void SetNativeDirectories()
    {
        if(directories.Count() != 1)
        {
            //TODO: add support for multiple directories
            throw new NotImplementedException("current implementation only supports exactly one directory");
        }

        if (0 == SetDllDirectory(directories.First()))
        {
            throw new Exception("SetDllDirectory failed with error " + Marshal.GetLastWin32Error());
        }
    }

    private void AddManagedHandler()
    {
        AppDomain currentDomain = AppDomain.CurrentDomain;
        currentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
    }

    private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        IEnumerable<string> candidates = FindCandidates(new AssemblyName(args.Name));
        return Assembly.LoadFrom(candidates.First());
    }

    private static IEnumerable<string> FindCandidates(AssemblyName assemblyname)
    {
        List<string> candidates = new List<string>();
        foreach (var path in directories)
        {
            string candidate = string.Format(@"{0}{1}.dll", path, assemblyname.Name);
            if (File.Exists(candidate))
            {
                candidates.Add(candidate);
            }
        }
        if (!candidates.Any())
        {
            throw new FileNotFoundException(string.Format("Can not find assembly: '{0}.dll'", assemblyname.Name));
        }
        return candidates;
    }
}