6

特定のeventArgsでイベントが発生したときに、オブジェクト(たとえばFoo)が特定のメソッド(たとえば)を呼び出すことを確認する単体テストがあります。Bar上記のメソッドをモックするために、仮想を使用してFooクラスをスタブします

Mock<Foo> stubbedFoo = new Mock<Foo>(mockEventProvider);

mockEventProvider.Raise( x => x.MyEvent += null, myEventArgs ) //fire the event
stubbedFoo.Verify(foo => foo.Bar()); verify Bar is called as a result

ただし、上記が失敗した場合、Fooオブジェクトがイベントで構築されていないため、Barは呼び出されません。ただし、次のような行を追加すると、次のようになります。

Mock<Foo> stubbedFoo = new Mock<Foo>(mockEventProvider);
var workAround = stubbedFoo.Object //adding this workaround will work
mockEventProvider.Raise( x => x.MyEvent += null, myEventArgs ) //fire the event
stubbedFoo.Verify(foo => foo.Bar()); verify Bar is called as a result

get on .Objectを呼び出すと、モックがオブジェクトを構築するように強制されるため、これは機能します。この行を追加するよりもエレガントな解決策はありますか?

4

1 に答える 1

1

私はあなたができるとは思わない。moqソースをチェックアウトして調べましたが、電話をかけるまで、からのプロキシインターセプターが実際に作成されているようには見えません.Object。このトレースを見てください:

public object Object
{
    get { return this.GetObject(); }
}

private object GetObject()
{
    var value = this.OnGetObject();
    this.isInitialized = true;
    return value;
}

に続く

protected override object OnGetObject()
{
    if (this.instance == null)
    {
        this.InitializeInstance();
    }

    return this.instance;
}

これはどれですか:

private void InitializeInstance()
{
    PexProtector.Invoke(() =>
    {
        this.instance = proxyFactory.CreateProxy<T>(
            this.Interceptor,
            this.ImplementedInterfaces.ToArray(),
            this.constructorArguments);
    });
}

ProxyFactoryは実際にオブジェクトを作成し、プロキシでラップします

public T CreateProxy<T>(ICallInterceptor interceptor, Type[] interfaces, object[] arguments)
{
    var mockType = typeof(T);

    if (mockType.IsInterface)
    {
        return (T)generator.CreateInterfaceProxyWithoutTarget(mockType, interfaces, new Interceptor(interceptor));
    }

    try
    {
        return (T)generator.CreateClassProxy(mockType, interfaces, new ProxyGenerationOptions(), arguments, new Interceptor(interceptor));
    }
    catch (TypeLoadException e)
    {
        throw new ArgumentException(Resources.InvalidMockClass, e);
    }
    catch (MissingMethodException e)
    {
        throw new ArgumentException(Resources.ConstructorNotFound, e);
    }
}
于 2012-10-08T21:55:55.090 に答える