2014-09-03 11 views
18

Sto provando a creare un test unitario utilizzando Moq che verifica il provider MongoDB.AspNet.Identity V2. Questa linea mi sta dando dolore:Impossibile istanziare il proxy ... Impossibile trovare un costruttore senza parametri

var appUser = new Mock<PreRegistrationMVC.Models.ApplicationUser>(); 
var userStore = new Mock<MongoDB.AspNet.Identity.UserStore<PreRegistrationMVC.Models.ApplicationUser>>(); 

Sembra che lo userStore non instanzia correttamente qui è l'errore.

Castle.DynamicProxy.InvalidProxyConstructorArgumentsException was unhandled by user code 
    HResult=-2147024809 
    Message=Can not instantiate proxy of class: MongoDB.AspNet.Identity.UserStore`1[[MVC.Models.ApplicationUser, MVC, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]. 
Could not find a parameterless constructor. 
    Source=Moq 
    StackTrace: 
     at Castle.DynamicProxy.ProxyGenerator.CreateClassProxyInstance(Type proxyType, List`1 proxyArguments, Type classToProxy, Object[] constructorArguments) 
     at Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors) 
     at Moq.Proxy.CastleProxyFactory.CreateProxy(Type mockType, ICallInterceptor interceptor, Type[] interfaces, Object[] arguments) 
     at Moq.Mock`1.<InitializeInstance>b__2() 
     at Moq.PexProtector.Invoke(Action action) 
     at Moq.Mock`1.InitializeInstance() 
     at Moq.Mock`1.OnGetObject() 
     at Moq.Mock.GetObject() 
     at Moq.Mock.get_Object() 
     at Moq.Mock`1.get_Object() 
     at MVC_Tests.Identity.Accounts.AccountController_Test.TestSuccessfulRegister() in c:\Users\Tim\Documents\Visual Studio 2013\Projects\PreRegistrationApp\MVC_Tests\Identity\Accounts\AccountController_Test.cs:line 108 
    InnerException: 

Sono completamente nuovi per MOQ così Cerco: Che tipo di impostazioni sono necessarie per Moq creare un'istanza di questo? C'è qualcosa nella classe UserStore che non funzionerà bene con Moq?

Grazie per la lettura.

risposta

24

MOQ è adatto per le interfacce di derisione, ma non funziona molto bene con le classi concrete. Così, invece di scherno classe concreta, chiedere l'inteface:

var userStore = new Mock<IUserStore<PreRegistrationMVC.Models.ApplicationUser>>(); 

anche ApplicationUser dovrebbe essere POCO, quindi non è necessario prendere in giro, basta creare la sua istanza, senza MOQ e l'uso in test.

+0

Oh che ha funzionato! Grazie! :) – ChiliYago

+0

Grande ha funzionato. Un'altra cosa potresti anche guidarmi quali sono le cose che dovrei prendere in giro. Per esempio sto lavorando con qualche architettura di livello e voglio solo testare un livello e il livello che voglio testare ha anche qualche altra dipendenza di livello. Quindi cosa dovresti suggerire? – Naveen

+0

@Naveen quello che chiedi è un argomento molto ampio e i commenti non sono il posto migliore per una discussione. La mia raccomandazione è di leggere un libro sui test unitari - uno di Roy Osherove è buono. Entra nei dettagli del problema che stai affrontando. – trailmax

3

Ho avuto questo problema. Avevo scritto ...

var x = new Mock<Concrete>(); 

... invece di ...

var x = new Mock<IConcrete>(); 
4

Si può provare riferendosi comportamento Mock, come illustrato di seguito

Mock<testClass>(MockBehavior.Strict, new object[] {"Hello"}); 
+4

Poiché è param Parameter, potrebbe essere scritto più breve come 'new Mock (MockBehavior.Strict," Hello ");' – sschoof