无法使用Moles来模拟MVC框架

5

我试图为System.Web.Mvc DLL版本3生成moles,但是我遇到了以下错误:

 Moles : info : metadata : loading C:\TFS.as12.Projects\Project X\Main\Source\3rdPartyComponents\MVC3\System.Web.Mvc.dll
    Moles : info : compilation : output assembly name: System.Web.Mvc.Moles
Moles : warning : metadata : failed to load module System.Web.Mvc.dll:
Moles : warning : metadata : Inheritance security rules violated by type: 'System.Web.Mvc.CompareAttribute'. Derived types must either match the security accessibility of the base type or be less accessible.
Moles : warning : metadata : Inheritance security rules violated by type: 'System.Web.Mvc.RemoteAttribute'. Derived types must either match the security accessibility of the base type or be less accessible.
Moles : error : code : assembly contains no types or failed to load properly
  00:00:00.53> moles generator 1 errors, 3 warnings

    Moles compilation FAILED - 6,18794176354816s
C:\Program Files (x86)\Microsoft Moles\bin\Microsoft.Moles.targets(79,5): error MSB3073: The command ""C:\Program Files (x86)\Microsoft Moles\bin\moles.exe" @"C:\TFS.as12.Projects\Project X\Main\Source\X.Web\X.Web.Base.Mvc.UnitTest\obj\Debug\Moles\moles.args"" exited with code -1002.

我在微软论坛上看到了更多关于这个问题的提问,但从未看到答案。 有人有解决方案吗?


非常令人失望 - MVC 的开发者是 .NET 社区中最热衷于单元测试的人之一...当然他们会想要使用 Mole 框架! - Stephen Swensen
3个回答

3
这与一个已知问题有关。如果您想在MVC3中使用Moles,可以按照以下步骤操作(我已经这样做了):
  1. 下载MVC3 源代码
  2. 从Properties/AssemblyInfo.cs中删除[SecurityTransparent]。
  3. 使用sn.exe从真正的MVC dll中提取MS公钥:"sn -e System.Web.Mvc.dll ms_public_key.snk"
  4. 告诉VS在签名您的虚假MVC dll时使用该公钥(您可以在项目属性下执行此操作,签名)。确保您选中了“仅延迟签名”框。
  5. 构建。现在您有一个使用MS公钥签名的虚假MVC dll。但是您不能将其用于任何事情,因为它无法通过签名验证。
  6. 再次使用sn.exe为您的虚假dll注册跳过验证:"sn -Vr System.Web.Mvc.dll" <--- 这需要是您的虚假文件
  7. 使用gacutil.exe将您的虚假文件放入全局程序集缓存: "gacutil -if System.Web.Mvc.dll" <--- 再次,这是虚假的文件
  8. 运行moles。我强烈建议您模拟整个dll,因为您不想再次执行此操作。
  9. 删除跳过验证:"sn -Vu System.Web.Mvc.dll" <--- 虚假的文件
  10. 恢复真实的dll:"gacutil -if System.Web.Mvc.dll" <--- 真实的文件
  11. 删除您的虚假MVC dll,以防有人意外使用它。
在第8步生成的System.Web.Mvc.Moles.dll将引用真实的MVC dll,这要归功于您所做的公钥切换。您可以使用它来存根/模拟MVC类,任意修改。

我在签署这个dll并构建它时遇到了两个问题:
  1. 由于[assembly: InternalsVisibleTo("System.Web.Mvc.Test")]:强名称签名的程序集必须在其InternalsVisibleTo声明中指定公钥。
  2. 当我删除了那行代码时:错误1:在签署程序集时发生加密失败--'密钥文件'ms_public_key.snk'缺少签署所需的私钥'。
你能帮我吗?
- mrzepa
1
我已经更新了第四步。你必须延迟签名,因为你不能仅使用公钥进行签名。 - bhamlin

0
为了补充@bhamlin提到的内容,在步骤#2中,我还需要在AssemblyInfo.cs中进行以下更改以生成moles:
修改
[assembly: AllowPartiallyTrustedCallers]

[assembly: AllowPartiallyTrustedCallers(PartialTrustVisibilityLevel = PartialTrustVisibilityLevel.NotVisibleByDefault)]

这是在 System.ComponentModel.DataAnnotations.dll 中定义的内容。

派生类型必须匹配基类型的安全可访问性或者比基类型更少的可访问性。

CompareAttribute 的基类是 ValidationAttribute,并且在此程序集中。


0
您可以尝试排除问题类型:
<Moles ...
   <StubGeneration ...
       <Types>
          <Remove TypeName="System.Web.Mvc.CompareAttribute" />
          <Remove TypeName="System.Web.Mvc.RemoteAttribute" />
       </Types>
   <MoleGeneration>
       <Types>
          <Remove TypeName="System.Web.Mvc.CompareAttribute" />
          <Remove TypeName="System.Web.Mvc.RemoteAttribute" />
       </Types>
   </MoleGeneration>

很遗憾,它不起作用。清除后跟随个别添加也不行。 - Stephen Swensen
当使用[assembly: MoledType(typeof(System.Web.Mvc...))]来针对程序集中的特定类型时,也无法正常工作。 - Stephen Swensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接