2011-09-14 13 views
10

seguito è la mia generica interfaccia repository di baseMoq Parametri TargetParameterCountException: parametro Count mancata corrispondenza Eccezione

public interface IRepository<T> 
{ 
    IQueryable<T> AllIncluding(params Expression<Func<T, 
           object>>[] includeProperties); 
} 

mia entità

public class Sdk 
{ 
    public Sdk() 
    { 
     this.Identifier = Guid.NewGuid().ToString(); 
    } 

    public virtual ICollection<Resource> AccessibleResources { get; set; } 

    public string Identifier { get; set; }  
} 

e che segue è il repo specifica

public interface ISdkRepository : IRepository<Sdk> 
{ 
} 

ora sono provare a testare un controller, usando moq

seguito è il codice che sto cercando di testare

public ActionResult GetResources(string clientId) { 
     var sdkObject = sdkRepository 
          .AllIncluding(k => k.AccessibleResources) 
          .SingleOrDefault(k => k.Identifier == clientId); 
     if (sdkObject == null) 
      throw new ApplicationException("Sdk Not Found"); 
     return Json(sdkObject.AccessibleResources.ToList()); 
    } 

usando seguente prova

[Test] 
public void Can_Get_GetResources() 
{ 
    var cid = Guid.NewGuid().ToString(); 
    var mockRepo = new Moq.Mock<ISdkRepository>(); 
    var sdks = new HashSet<Sdk>() 
    { 
     new Sdk() 
     { 
      Identifier = cid, 
      AccessibleResources = new HashSet<Resource>() 
      { 
       new Resource() 
       { 
        Id = Guid.NewGuid(), 
        Description = "This is sdk" 
       } 
      } 
     } 
    }; 
    mockRepo.Setup(k => k. 
     AllIncluding(It.IsAny<Expression<Func<Sdk,object>>[]>())) 
         .Returns(sdks.AsQueryable); 
    var sdkCtrl = new SdksController(mockRepo.Object); 
    var returnedJson=sdkCtrl.GetResources(cid); 
    returnedJson.ToString(); 
} 

e sta gettando:

System.Reflection.TargetParameterCountException: Parametro conteggio mancata corrispondenza

Non so perché?

+0

Can incollare la traccia dello stack? – Raghu

risposta

4

Credo che tu abbia colpito alcune limitazioni qui con Moq. Non gestisce bene i parametri di espressione perché può essere passato a espressioni come valori. Moq non ha modo di sapere quale parte dell'espressione deve essere risolta e cosa fa parte della firma.

Inoltre, non riesco a ricordare quanto bene Moq gestisce i parametri xx [] ma è abbastanza probabile che tu abbia una combinazione di due problemi qui.

Sei in grado di creare una classe che espone il set di espressioni come una proprietà? In tal caso potrebbe essere possibile modificare la firma di AllIncluding e comunicare a Moq la corrispondenza su qualsiasi istanza di tale classe.

Aggiornamento

Al momento di rispondere a questa è stata una limitazione, ma è ora possibile. Vedere la risposta di Oleksandr Lytvyn

+0

per favore guarda nella risposta di Oleksandr Lytvyn. – Marcel

28

Anche se c'è una risposta contrassegnata come accettata, credo che ci sia un modo per deridere il repository correttamente.

Invece di

mockRepo.Setup(k => k.AllIncluding(It.IsAny<Expression<Func<Sdk, object>>[]>())) 
        .Returns(sdks.AsQueryable); 

utilizzare

mockRepo.Setup(k => k.AllIncluding(It.IsAny<Expression<Func<Sdk, object>>[]>())) 
        .Returns((Expression<Func<Sdk, 
         object>>[] includeProperties) => sdks.AsQueryable()); 
+1

Mi ha salvato la giornata) Ho avuto esattamente lo stesso problema esattamente nello stesso modo, la tua proposta funziona! –

+0

Grazie! mi ha salvato colpendo circa – trailmax

+0

Fantastico! Lavorato. C'è una spiegazione per come funziona (cosa fa in realtà)? – Marcel

7

Un'altra soluzione per risolvere questo problema è quello di utilizzare: .AsQueryable() invece di .AsQueryable.

0

Per altre persone in cerca di risposta a questo la soluzione per me era aggiungere lo stesso numero di parametri in Setup come nell'espressione in Returns.

Ad esempio:

Non funziona con l'argomento diverso contano

mock.Setup(x => x.DoSomething(It.IsAny<string>(), It.IsAny<string>())) 
       .Returns((string s) => s.ToLower()); 

Lavorare con la stessa quantità di argomenti di espressione in Returns come in Setup

mock.Setup(x => x.DoSomething(It.IsAny<string>())) 
       .Returns((string s1, string s2) => s1.ToLower()); 
Problemi correlati