问题:如何在运行测试时让NUnit可以使用本机库,以便可以在启动时加载它?
背景:我最近开始使用NUnit进行测试,而我正在努力设置一个涉及非托管(本机)库的测试(让我们称之为x.dll
)。我正在测试的项目是围绕这个库管理的c ++ / CLI包装器。我有NUnit c#test项目引用包装器,所以我可以使用那里定义的函数。问题是,当我运行测试时,会抛出System.IO.FileNotFoundException
,表示无法找到x.dll
。我需要以某种方式将NUnit指向它的位置,或者将它复制到执行目录(隐藏在temp
目录中的某个位置)但是在相当广泛的搜索之后找不到如何做到这一点 - 可能错过了正确的关键字。
我在Visual Studio中使用NUnit 3扩展,测试项目是使用模板创建的,也可用作扩展。
答案 0 :(得分:0)
使用非托管程序集的技巧是要注意操作系统使用与.NET查找托管引用的方式不同的方法找到它们。
作为复习:在路径上找到非托管程序集,而在AppBase或其下的私有binpath中找到托管程序集。
我的猜测是VS正在将x.dll
复制到输出目录中。如果没有,您应该通过将CopyLocal设置为true来实现。现在,在运行测试之前,将该目录添加到路径的开头。如果您尚未使用脚本,则可能需要创建一个脚本才能执行此操作。
答案 1 :(得分:0)
因为我希望测试是自包含的并且能够使用Resharper或Visual Studio Test框架(使用NUnit扩展)等工具运行,所以我试图避免像@Charlie建议的那样运行脚本测试,因为我不会知道如何将结果与这些工具集成。
但是,我设法找到一个有趣的属性void RegisterLibs()
{
const string pathVar = "Path";
const string fileUriTag = "file:///";
// Get executable path
var exePath = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
if (exePath.StartsWith(fileUriTag))
exePath = exePath.Remove(0, fileUriTag.Length);
// Extract directory
var exeDir = System.IO.Path.GetDirectoryName(exePath);
// Get path variable
var pathVal = Environment.GetEnvironmentVariable(pathVar) ?? "";
// Simple check for architecture.
// 4-byte pointer => 32bit
// 8-byte pointer => 64bit
var arch = IntPtr.Size == 4 ? "Win32" : "x64";
// Prepare new entry for path
var libPath = $"{exeDir}\\{arch};";
if (pathVal.Contains(libPath))
return;
// Prepend the entry
pathVal = pathVal.Insert(0, libPath);
// Update path variable
Environment.SetEnvironmentVariable(pathVar, pathVal);
}
,可以用来标记函数SQL DEMO。值得庆幸的是,这是在运行测试的同一过程中实现的,因此我们可以使用它以优雅的方式更改Path变量。这是我用来改变Path的代码,它也可以区分运行它们的架构:
[TestFixture]
public class UnitTests
{
[OneTimeSetUpAttribute]
public void TestFixtureSetup()
{
RegisterLibs();
}
[Test]
public void Test1()
{
// Path is set-up here
// ...Your test code...
}
}
然后可以在测试中使用:
// Object definition
function OriginalOwner(prop) { this.prop = prop; }
OriginalOwner.prototype.aFunc = function(arg) { return this.prop + arg; }
// Object instance
var owner = new OriginalOwner("Returned ");
// Example function bindings
var boundFunc = owner.aFunc.bind(owner);
var reboundFunc = boundFunc.bind(boundFunc.owner, "myArgument");
// Calling rebound function
console.log(reboundFunc()); // outputs "Returned myArgument"