2012-08-31 15 views
5

Ho un test unitario per verificare che un oggetto (ad esempio Foo) chiami un determinato metodo (ad esempio Bar) quando un evento viene generato con determinati eventiArg. Per prendere in giro il suddetto metodo, io uso virtuale e stub il Foo classeCome forzare moq per chiamare il costruttore?

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 

Tuttavia, quanto sopra non è riuscita, Bar non sarà chiamato, a quanto pare perché l'oggetto Foo non è costruito evento. Tuttavia, se aggiungo una riga come di seguito:

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 

che funzionerà, perché chiamando salire sul .Object apparentemente costringe finto per costruire l'oggetto. C'è una soluzione più elegante di aggiungere questa linea?

risposta

1

Non credo che sia possibile. Ho controllato lo moq source e l'ho analizzato e non sembra che l'intercettatore del proxy da castle venga effettivamente creato finché non si chiama .Object. Guarda a questo tracciato:

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

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

Seguito da

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

    return this.instance; 
} 

che fa questo:

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

ProxyFactory crea effettivamente l'oggetto e lo avvolge in 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 vedi .. pensi che questo sia un difetto nel moq? –

+0

Direi che probabilmente è stata una decisione intenzionale, ma moq è open source quindi puoi cambiarlo se vuoi – devshorts

Problemi correlati