NUnit 3无法测试含动态程序集生成的代码问题求助
解决NUnit 3测试中动态编译找不到依赖DLL的问题
你遇到的问题很典型:业务逻辑里的动态编译代码在常规应用流程中运行正常,但用NUnit 3执行单元测试时,触发了CS0006错误,提示找不到Person.dll和Employee.dll——哪怕这些DLL明明和测试DLL放在同一个bin目录下。
问题根源
这并不是NUnit 3的Bug,而是它的测试运行机制导致的:
- NUnit 3默认的工作目录并不是测试DLL所在的输出bin目录,而是NUnit测试运行器的启动目录(比如NUnit GUI的安装目录,或是VS测试运行器使用的临时目录)
- 动态编译的
CompilerParameters默认只会在当前工作目录、系统GAC里查找引用的程序集,自然找不到bin目录下的依赖文件。
解决方案
下面提供几个实用的解决思路,按推荐优先级排序:
方案1:指定依赖DLL的绝对路径(最可靠)
修改动态编译的代码,先获取当前程序集(测试DLL或业务逻辑DLL)所在的目录,再用绝对路径添加引用,确保编译器能精准定位到文件:
// 获取当前运行程序集的所在目录 string assemblyDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); CompilerParameters cp = new CompilerParameters(); cp.GenerateExecutable = false; cp.GenerateInMemory = true; cp.TreatWarningsAsErrors = false; // 用绝对路径添加依赖DLL cp.ReferencedAssemblies.Add(Path.Combine(assemblyDir, "Employee.dll")); cp.ReferencedAssemblies.Add(Path.Combine(assemblyDir, "Person.dll")); CompilerResults cr = provider.CompileAssemblyFromSource(cp, "someCode"); if (cr.Errors.Count > 0) {..}
这个方法不受运行环境工作目录的影响,无论用NUnit GUI、VS测试运行器还是CI环境执行测试都能生效。
方案2:修改NUnit GUI的工作目录(仅适用于本地GUI测试)
如果不想修改代码,仅在本地用NUnit GUI运行测试时,可以手动指定工作目录:
- 打开NUnit GUI并加载你的测试DLL
- 点击菜单栏的
Project->Edit Project - 在弹出的窗口中找到
Working Directory选项,选择测试DLL所在的bin目录(比如bin\Debug或bin\Release) - 保存设置后重新运行测试
方案3:给CompilerParameters添加探测路径
另一种方式是把测试DLL所在目录添加到编译参数的AdditionalLibPaths中,让编译器自动去这个目录查找依赖:
string assemblyDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); CompilerParameters cp = new CompilerParameters(); cp.GenerateExecutable = false; cp.GenerateInMemory = true; cp.TreatWarningsAsErrors = false; // 添加依赖探测目录 cp.AdditionalLibPaths.Add(assemblyDir); // 直接用文件名添加引用,编译器会在探测目录中查找 cp.ReferencedAssemblies.Add("Employee.dll"); cp.ReferencedAssemblies.Add("Person.dll"); CompilerResults cr = provider.CompileAssemblyFromSource(cp, "someCode"); if (cr.Errors.Count > 0) {..}
这个方案适合有多个依赖目录的场景,灵活性更高。
内容的提问来源于stack exchange,提问作者Iftikhar Ali
相关产品推荐
相关产品推荐

