我在创建单元测试时发现了一个非常奇怪的问题,该问题仅在 Mono 运行时(包括 Mac 上的 Xamarin)中发生,但在 Visual Studio 中运行良好。我尽可能地隔离它,我无法判断它是否是 Mono、Moq 或 Castle DinamicProxy 的错误,尽管它仅在使用 Mono 运行时时崩溃。
这是代码:
using System;
using System.Collections.Generic;
using Moq;
namespace ConsoleApplication1
{
public interface ISomething<T>
{
List<T> DoSomething<U>(/*Func<T, U> expression*/);
}
public class Foo { }
public class Program
{
public static void Main(string[] args) {
var mock = new Mock<ISomething<Foo>>();
Console.WriteLine(mock.Object);
}
}
}
这是我知道的:
- 它在 Visual Studio 2012 中编译和运行。输出为“Castle.Proxies.ISomething`1Proxy”
- 与 Mono 运行时一起运行时,它不起作用。抛出异常(见下文)
- 如果我将声明从接口更改为抽象类,它适用于 Mono
- 如果我将返回类型从更改
List<T>
为其他任何类型,则它适用于 Mono - 如果我删除泛型类型
<U>
,它适用于单声道 - 使用来自http://mono-project.com的命令行构建在 Windows、Mac 和 Linux 下得到相同的结果
- 在 Windows 中,它在 Mono 2.10.9 中失败,但在 Xamarin.Studio (4.0.10) 中工作
- 在 Mac 中,它在 Xamarin.Studio (4.0.10) 中失败
- 我重新编译了 Moq 链接到最新的 DynamicProxy 版本(Castle.Core.3.2.0),没有改变行为。
虽然我在使用 Moq 时发现了这个问题,但我无法判断它是否与它有关,甚至是 DynamicProxy。部分例外如下,完整的可以在http://pastie.org/8203093找到
mono ConsoleApplication1.exe
[ERROR] FATAL UNHANDLED EXCEPTION: System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
at System.Collections.Generic.Dictionary`2[System.String,System.Reflection.Emit.GenericTypeParameterBuilder].get_Item (System.String key) [0x00000] in <filename unknown>:0
at Castle.DynamicProxy.Internal.TypeUtil.CloseGenericParametersIfAny (Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter emitter, System.Type[] arguments) [0x00000] in <filename unknown>:0
at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget (System.Type interfaceToProxy, System.Type[] additionalInterfacesToProxy, Castle.DynamicProxy.IInterceptor[] interceptors) [0x00000] in <filename unknown>:0
at Moq.Proxy.CastleProxyFactory.CreateProxy[ISomething`1] (ICallInterceptor interceptor, System.Type[] interfaces, System.Object[] arguments) [0x00000] in <filename unknown>:0
[....]
at Moq.Mock`1[ConsoleApplication1.ISomething`1[ConsoleApplication1.Foo]].<InitializeInstance>b__0 () [0x00000] in <filename unknown>:0
at Moq.PexProtector.Invoke (System.Action action) [0x00000] in <filename unknown>:0
at Moq.Mock`1[ConsoleApplication1.ISomething`1[ConsoleApplication1.Foo]].InitializeInstance () [0x00000] in <filename unknown>:0
at Moq.Mock`1[ConsoleApplication1.ISomething`1[ConsoleApplication1.Foo]].OnGetObject () [0x00000] in <filename unknown>:0
at Moq.Mock.GetObject () [0x00000] in <filename unknown>:0
at Moq.Mock.get_Object () [0x00000] in <filename unknown>:0
at Moq.Mock`1[ConsoleApplication1.ISomething`1[ConsoleApplication1.Foo]].get_Object () [0x00000] in <filename unknown>:0
at ConsoleApplication1.Program.Main (System.String[] args) [0x00000] in <filename unknown>:0