2012-08-31 15 views
5

Mam test jednostki, aby sprawdzić, czy dany obiekt (na przykład Foo) wywoła określoną metodę (na przykład Bar), gdy zdarzenie zostanie wywołane z pewnymi zdarzeniami eventArgs. Mock wspomnianą metodę, używam wirtualnych i skrótową klasęJak zmusić moq do wywołania konstruktora?

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 Jednakże powyższe nie powiodło, bar nie zostanie wywołana, prawdopodobnie dlatego, że obiekt nie jest zdarzenie Foo zbudowane. Jednakże jeśli dodać linię jak poniżej:

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 

To będzie działać, ponieważ powołanie się na .Object podobno wymusza makiety do budowy obiektu. Czy istnieje bardziej eleganckie rozwiązanie niż dodanie tej linii?

Odpowiedz

1

Nie sądzę, że możesz. Sprawdziłem numer moq source i przeszukałem go i nie wygląda na to, że interpreter proxy z castle jest rzeczywiście tworzony, dopóki nie zadzwonisz pod numer .Object. Spójrz na ten ślad:

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

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

Obserwowani przez

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

    return this.instance; 
} 

która robi to:

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

ProxyFactory faktycznie tworzy obiekt i zawija je w prokurentem

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); 
    } 
} 
+0

I widzisz .. myślisz, że to jest błąd w moq? –

+0

Powiedziałbym, że to była prawdopodobnie celowa decyzja, ale moq jest open source, więc możesz to zmienić, jeśli chcesz – devshorts

Powiązane problemy