2012-08-31 12 views
5

Tengo una prueba de unidad para verificar que un objeto (por ejemplo, Foo) llame a cierto método (por ejemplo, Bar) cuando se desencadena un evento con ciertos eventArgs. Para burlarse de dicho método, utilizo virtual y golpeo la clase¿Cómo forzar a moq a llamar al constructor?

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 Sin embargo, lo anterior no, Bar no se llamará, al parecer porque el objeto no es Foo evento construida. Sin embargo, si añado una línea como la siguiente:

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 

que va a funcionar, porque llamar a conseguir en .Object aparentemente obliga maqueta para construir el objeto. ¿Hay una solución más elegante que agregar esta línea?

Respuesta

1

No creo que puedas. Revisé el moq source y lo revisé y no parece que el interceptor de proxy del castle se haya creado hasta que llame al .Object. Mira esta traza:

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

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

Seguido de

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

    return this.instance; 
} 

que hace esto:

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

ProxyFactory realidad crea el objeto y lo envuelve en un proxy

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 mira ... ¿crees que esto es un defecto en moq? –

+0

Yo diría que esto fue probablemente una decisión intencional, pero moq es de código abierto, así que puedes cambiarlo si quieres – devshorts

Cuestiones relacionadas