C# 微软摩尔,动态仪器

C# 微软摩尔,动态仪器,c#,.net,moles,C#,.net,Moles,摩尔有两种使用方法: 人工 包括[组件:MoledType(类型(_-type-to-_仪器))] 指定[主机类型(“摩尔”)] 调用Microsoft.Moles.Framework.Moles.MoleRuntime.SetMole(委托存根、对象接收器、方法信息方法) 动态地 添加一个{project name}.moles文件:为mole指定程序集。例如 构建并包含对molesasemblies/{project_name}.Moles.dll的引用 使用M{class_name}自

摩尔有两种使用方法:

人工
  • 包括[组件:MoledType(类型(_-type-to-_仪器))]
  • 指定[主机类型(“摩尔”)]
  • 调用Microsoft.Moles.Framework.Moles.MoleRuntime.SetMole(委托存根、对象接收器、方法信息方法) 动态地
  • 添加一个{project name}.moles文件:为mole指定程序集。例如
    
    
  • 构建并包含对molesasemblies/{project_name}.Moles.dll的引用
  • 使用M{class_name}自动生成的mole类
  • 我注意到,使用动态程序集不需要测试项目声明“moled assemblies”属性。这减少了开销,开发人员只需用摩尔的主体类型来装饰每个测试方法;但进一步的测试不需要跟踪仪器的类型

    查看MolesAssembly中自动生成的代码(使用反汇编程序),很容易找到所需的instrumentation属性。然而,试图编写我自己的“mole程序集”(实际上是替换自动生成的程序集)不起作用,运行时抱怨需要检测我的类型。我很好奇我错过了什么

    我注意到自动生成的moles代码声明了必要的MoledAssembly属性。但是在我的测试中,测试项目似乎必须声明这个属性;它不能由项目的引用程序集声明。但是,对于自动生成的程序集,属性似乎可以声明为“外部”。这是基于我的假设,我可以通过分解自动生成的moles dll看到;我找不到其他的区别。然而,正如我试图解释的那样,从反汇编的自动生成的moles dll复制所有代码(和属性)并构建我自己的引用程序集在运行时失败,因为我没有在测试中标记需要插入指令的程序集(即,用MoledAssembly标记),尽管它在我引用的assAssembly中有标记

    --更新

    在这一点上(可能是由于我对我的代码缺少什么的误解),我觉得我们需要非常具体地说明程序集有什么。假设我们有4个DLL:

  • Test.dll:mstest项目。未声明
    MoledAssembly
  • Moles.dll:在项目中使用
    *.Moles
    文件时自动生成的dll。引用第四个dll(请参见#4)
    Sealed
    。声明
    [组件:MoledAssembly(“密封”)]
    。请注意,我正在尝试在没有此dll的情况下完成手动摩尔注入-它只是一个概念参考,或用于我们的讨论或故障排除
  • MyMoles.dll:我的源代码编译版本是自动生成的
    Moles.dll
  • Sealed.dll:包含测试中的代码

  • 在回答/评论/问题中-让我们根据此列表参考每个零件。

    当使用非自动生成的moled装配时,装配属性是必需的。Moles工具for visualstudio会在必要时自动提醒编译器存在生成的程序集

    通过VisualStudio添加Moles部件时,在生成项目之前不会生成mole部件。此外,不可能为不存在的程序集包含程序集属性。这样做将导致编译器失败。因此,Moles还需要向编译器命令行动态添加命令,以生成moled程序集,然后从项目中正确引用它们

    使用手动生成的Moles部件时,必须包含部件属性,因为Moles工具不知道它的存在,因为部件不是自动生成的。程序员必须为鼹鼠做这项工作

    如果您想走到这一步,可以在编译器启动之前使用代码生成。PERL可以在需要时轻松地注入必要的汇编属性。当编译器收到代码时,它将已经注入属性

    支持我答案的实验:

    我可以复制你的问题。通过在using语句块下面添加assembly属性,我也能够解决这个问题。我采取了以下步骤来构建示例应用程序:

  • 创建了一个名为ClassLibrary2的.NET4.0C#类库项目
  • 在Class1中创建了以下方法:

    公共字符串TestString(){返回“原始值”。;}

  • 通过右键单击TestString方法声明,然后选择CreateUnitTests,创建了一个测试项目(TestProject1)。。。(懒惰,我知道。)

  • 从ClassTest.cs中删除了额外的垃圾,留下TestStringTest()
  • 为mscorlib添加了moles组件。(回想起来,这是另一个懒惰的快捷方式,也是一个不必要的步骤。我在这里记下了它,因为这是我做的。)
  • 为ClassLibrary2添加了moles组件
  • 使用默认的任意CPU配置文件编译的解决方案
  • 使用Redgate(抱歉,@payo)反编译ClassLibrary2.Moles
  • 添加了一个名为MoleClassLibrary的新类库项目
  • 将反编译的MClass1和SClass1代码复制到MoleClassLibrary中
  • 已从TestProject1中删除Class1.moles文件和程序集
  • 从TestProject1中删除了(不必要的)mscorlib.moles文件和程序集
  • 向TestProject1添加了MoleClassLibrary引用
  • 更新了ClassTest.cs中的using语句
  • 构建解决方案
  • 使用Visual Studio 2010测试视图窗口执行TestStringTest()
  • 测试失败,生成详细信息:
  • 试验方法 TestProject1.ClassTest.TestStringTest 引发异常: Microsoft.Moles.Framework.Moles.MoleNotInstrumentedException: 系统。字符串 ClassLibrary1.Class1.TestString()是 N
    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);
            }
        }
    }