2013-07-10 20 views
18

Dire che ho una classe "ClasseA", che ha una dipendenza da una classe "ClasseB" (iniettata nel ctr di Classe A). Voglio prendere in giro ClassB in modo da poter testare ClassA in isolamento. Entrambe le classi sono interne.Mocking di classi interne con Moq per il test dell'unità

mi corregga se sbaglio, ma sembra che Moq può deridere solo una classe se è pubblica, ha un costruttore senza parametri pubblica, ed i metodi da deriso sono public virtual. Non voglio davvero rendere queste classi pubblicamente visibili. Mi manca qualcosa con Moq, o non è adatto per quello che voglio fare?

Immagino di poter creare un'interfaccia (ad esempio "IClassB") implementata da ClassB, inserirla in ClassA e simulare l'interfaccia. ClassB può ancora essere interno (anche se mi rendo conto che i metodi dell'interfaccia dovrebbero essere pubblici). Mentre ciò funzionerebbe, mi sento a disagio nel creare molte interfacce, il cui unico scopo è quello di supportare il test delle unità. Pensieri?

risposta

45

Si potrebbe fare interni visibili a Moq aggiungendo InternalsVisibleToAttribute in assembly.cs del vostro progetto, in questo modo:

Perché "DynamicProxyGenAssembly2" e non "Moq"? È il nome dell'assembly dinamico creato per contenere i tipi di proxy generati dinamicamente (tutto ciò è gestito da un'altra libreria, DynamicProxy di Castle) che viene utilizzata da Moq. Quindi esponi i tipi all'assembly proxy dinamico, non a Moq stesso.

Ma, qual è il punto della lezione di derisione se non c'è un membro che sostituisce? Non prenderai in giro nulla e tutte le chiamate useranno l'effettiva implementazione. La vostra seconda soluzione,

Credo che avrei potuto creare un'interfaccia (diciamo "IClassB"), che implementa ClassB, iniettare che in ClassA, e deridere l'interfaccia invece.

è quello che farei normalmente. Il suo scopo è molto più di "per supportare l'unità test di simulazione" - ti aiuta a costruire componenti accoppiati male, che è sempre qualcosa per cui vale la pena mirare.

+0

Utile da sapere, grazie. Tuttavia ora ho deciso di mantenere pubbliche le classi (almeno quelle in fase di test). Penso che stavo rimanendo impiccato a cercare di rendere tutto interno, ma è solo un'app desktop quindi non è così cruciale come sarebbe in (dire) un assembly/API che veniva dato ai clienti. –

+0

Post molto utile, ero molto confuso da InternalsVisibleTo ("IntegrationTests") non funzionava. Quindi aveva senso che non fosse il mio assembly ad accedervi ma l'assembly creato dinamicamente da Castle. –