Moles可以通过两种方式使用:
<Moles xmlns="http://schemas.microsoft.com/moles/2010/">
<Assembly Name="Samples.Moles"/>
</Moles>
我注意到使用动态程序集不需要测试项目声明'moled assemblies'属性。这减少了开销,开发人员只需要使用主机类型为每个测试方法装饰摩尔;但进一步测试不需要跟踪要测量的类型。
查看molesassemblies中自动生成的代码(使用反汇编程序),很容易找到所需的检测属性。然而,尝试编写我自己的'mole assembly',基本上替换自动生成的那个,并不起作用,运行时抱怨我的类型需要进行检测。我很好奇我错过了什么。
我注意到自动生成的moles代码声明了必要的MoledAssembly属性。但在我的测试中,测试项目似乎必须声明这个属性;它不能由引用的程序集声明到项目。但是,在使用自动生成的程序集的情况下,它将属性可以声明为“outside”。这是我的假设,我可以看到拆卸自动生成的痣dll;我找不到任何其他差异。但是,正如我试图解释的那样,从反汇编的自动生成的moles dll复制所有代码(和属性)并构建我自己引用的程序集在运行时失败,说我没有标记所需的组装测试要进行检测(即用MoledAssembly标记) - 它只是在我引用的asssembly中。
- 更新
此时(可能是由于我对我的代码缺失的误解)我觉得我们需要非常具体地了解哪些程序集具有什么。假设我们有4个dll:
MoledAssembly
。*.moles
文件时创建的自动生成的dll。引用第4个dll,(参见#4)Sealed
。声明[assembly: MoledAssembly("Sealed")]
。请注意,我正在尝试在没有此dll的情况下完成手动鼹鼠注射 - 它只是一个概念性参考或用于我们的讨论或故障排除。Moles.dll
。在答案/评论/问题中 - 让我们根据此列表参考每个部分。
答案 0 :(得分:4)
使用未自动生成的moled程序集时,必须使用assembly属性。 Moles Tools for Visual Studio 会自动提醒编译器存在生成的程序集。
通过Visual Studio添加Moles装配时,在构建项目之前不会生成mole装配。此外,不可能为尚不存在的程序集包含程序集属性。这样做会导致编译器失败。因此,Moles还必须动态地向编译器命令行添加命令,生成moled程序集,然后从项目中正确引用它们。
使用手动生成的moled程序集时,必须包含一个程序集属性,因为Moles工具由于程序集不是自动生成而不知道它的存在。程序员必须为Moles做好工作。
如果你想到目前为止,你可以在编译器参与之前使用代码生成。 PERL可以根据需要轻松注入必要的装配属性。当编译器收到代码时,它已经注入了属性。
支持我的答案的实验:
我能够重现你的问题。我还能够通过在 using 语句块下添加一个程序集属性来解决问题。我采取了以下步骤来构建我的示例应用程序:
在Class1中创建了以下方法:
public string TestString(){return“原始值。”; } 强>
创建一个测试项目(TestProject1),方法是右键单击TestString方法声明,然后选择创建单元测试... (懒惰,我知道。)
测试方法 TestProject1.Class1Test.TestStringTest 抛出异常: Microsoft.Moles.Framework.Moles.MoleNotInstrumentedException: System.String ClassLibrary1.Class1.TestString()是 未检测解决此问题 问题,添加以下属性 测试项目:
使用Microsoft.Moles.Framework; [部件: MoledAssembly(typeof运算(ClassLibrary1.Class1))]
我将推荐的程序集属性添加到文件中。执行此操作后,测试方法成功运行。我怀疑编译器会自动引用生成的moled程序集,从而无需使用assembly属性。我尝试将MoleClassLibrary二进制文件复制到MolesAssemblies目录并创建一个MoleClassLibrary.moles文件,以测试该理论。仅当我包含assembly属性时才通过测试。这个结果对我的假设没有定论。
这是Class1Test.cs的代码:
using ClassLibrary1;
using Microsoft.Moles.Framework;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MoleClassLibrary;
[assembly: MoledAssembly(typeof(ClassLibrary1.Class1))]
namespace TestProject1
{
[TestClass()]
public class Class1Test
{
[TestMethod()]
[HostType("Moles")]
public void TestStringTest()
{
var target = new Class1();
var expected = "Mole value.";
string actual;
MClass1.AllInstances.TestString = value => expected;
actual = target.TestString();
Assert.AreEqual(expected, actual);
}
}
}