I am using the latest Moq (4.2.1502.911) in Visual Studio 2013 to mock an internal interface contained in another project. Both projects are signed with the same key. After searching here and elsewhere on the web I figured I had to add InternalsVisibleTo for the test assembly and "DynamicProxyGenAssembly2", using Moq's public key like so:
我正在使用Visual Studio2013中最新的MOQ(4.2.1502.911)来模拟另一个项目中包含的内部接口。这两个项目都使用相同的密钥签名。在Web上搜索了此处和其他位置后,我认为必须使用Moq的公钥为测试程序集添加InternalsVisibleTo和“DynamicProxyGenAssembly”,如下所示:
[assembly: InternalsVisibleTo("UnitTestProject1, PublicKey=00240000048000009...
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=002400000...
Now when I run my test method I still get the following error:
现在,当我运行我的测试方法时,我仍然得到以下错误:
Test Name: TestMethod1
Test FullName: UnitTestProject1.Class1Test.TestMethod1
Test Source: c:\Users\******\Documents\Visual Studio 2013\Projects\MoqTest\UnitTestProject1\UnitTest1.cs : line 13
Test Outcome: Failed
Test Duration: 0:00:00,0693592
Result Message:
Test method UnitTestProject1.Class1Test.TestMethod1 threw exception:
System.TypeLoadException: Le type 'Castle.Proxies.IFooProxy' de l'assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=a621a9e7e5c32e69' essaye d'implémenter une interface inaccessible.
Result StackTrace:
à System.Reflection.Emit.TypeBuilder.TermCreateClass(RuntimeModule module, Int32 tk, ObjectHandleOnStack type)
à System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
à System.Reflection.Emit.TypeBuilder.CreateType()
à Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.CreateType(TypeBuilder type)
à Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType()
à Castle.DynamicProxy.Generators.InterfaceProxyWithoutTargetGenerator.GenerateType(String typeName, Type proxyTargetType, Type[] interfaces, INamingScope namingScope)
à Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.<>c__DisplayClass1.<GenerateCode>b__0(String n, INamingScope s)
à Castle.DynamicProxy.Generators.BaseProxyGenerator.ObtainProxyType(CacheKey cacheKey, Func`3 factory)
à Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.GenerateCode(Type proxyTargetType, Type[] interfaces, ProxyGenerationOptions options)
à Castle.DynamicProxy.DefaultProxyBuilder.CreateInterfaceProxyTypeWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
à Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, IInterceptor[] interceptors)
à Moq.Proxy.CastleProxyFactory.CreateProxy(Type mockType, ICallInterceptor interceptor, Type[] interfaces, Object[] arguments)
à Moq.Mock`1.<InitializeInstance>b__2()
à Moq.PexProtector.Invoke(Action action)
à Moq.Mock`1.InitializeInstance()
à Moq.Mock`1.OnGetObject()
à Moq.Mock`1.get_Object()
à UnitTestProject1.Class1Test.TestMethod1() dans c:\Users\******\Documents\Visual Studio 2013\Projects\MoqTest\UnitTestProject1\UnitTest1.cs:ligne 15
(In English: System.TypeLoadException : Type 'Castle.Proxies.IFooProxy' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=a621a9e7e5c32e69' is attempting to implement an inaccessible interface.
)
(英文:System.TypeLoadException:从程序集“”DynamicProxyGenAssembly“”中键入“”Castle.Proxies.IFooProxy“”,版本=0.0.0.0,区域性=中性,PublicKeyToken=a621a9e7e5c32e69“”正在尝试实现不可访问的接口。)
Is there something else to do to get this to work?
Here is a minimal compilable example: https://www.dropbox.com/s/c2slwq4do5ttp9p/MoqTest.zip?dl=0
还有没有别的办法可以让这件事奏效?下面是一个最小的可编译示例:https://www.dropbox.com/s/c2slwq4do5ttp9p/MoqTest.zip?dl=0
更多回答
Not true, that's what InternalsVisibleToAttribute is for. The above works when the assemblies are not signed.
不是这样的,这就是InternalsVisibleToAttribute的用途。当程序集未签名时,上述规则起作用。
So you are able to change "another" project - did not realize that. Note that your sample shows different public key from error... Usually test/proxy assemblies are not signed - you may need to actually manually build proxy that is signed with correct key for this to work.
所以你能够改变“另一个”项目--没有意识到这一点。请注意,您的示例显示了与错误不同的公钥...通常测试/代理程序集不进行签名--您可能需要实际手动构建使用正确密钥签名的代理,这样才能正常工作。
优秀答案推荐
Using the following Public Key value solved the issue for me:
使用以下公钥值为我解决了问题:
0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7
0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7
I initially tried to get the public key using sn.exe but I think the public key it returns is for Moq rather than DynamicProxyGenAssembly2. I got the above key from the Moq GitHub page:
我最初尝试使用sn.exe获取公钥,但我认为它返回的公钥是用于Moq的,而不是DynamicProxyGenAssembly 2。我从Moq GitHub页面获得了上面的密钥:
https://github.com/Moq/moq4/wiki/Quickstart
Https://github.com/Moq/moq4/wiki/Quickstart
// This assembly is the default dynamic assembly generated Castle DynamicProxy,
// used by Moq. Paste in a single line.
[assembly:InternalsVisibleTo("DynamicProxyGenAssembly2,PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
In my case, although the error message suggested to use the public key for Moq, the fix was to not use the public key, so:
在我的例子中,尽管错误消息建议对Moq使用公钥,但修复方法是不使用公钥,因此:
[assembly:InternalsVisibleTo("DynamicProxyGenAssembly2")]
Or, in the csproj file:
或者,在csproj文件中:
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>DynamicProxyGenAssembly2</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
更多回答
我是一名优秀的程序员,十分优秀!