Mono ランタイム (Mac 上の Xamarin を含む) でのみ発生する単体テストを作成しているときに、非常に奇妙な問題を発見しましたが、Visual Studio 内では正常に実行されます。可能な限り分離しましたが、Mono ランタイムを使用している場合にのみクラッシュしますが、Mono、Moq、または Castle DinamicProxy のバグであるかどうかはわかりません。
これはコードです:
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