2011-12-22 10 views
8

Sto usando Moq per verificare il comportamento di alcuni metodi di annullamento. Utilizzando MockBehaviour.Strict ogni chiamata alla simulazione deve essere specificata durante il passaggio Arrange. Ciò si traduce in un sacco di test che non hanno alcun passaggio Assert (o Verifica). La condizione di pass è semplicemente che il test è stato eseguito senza generare un'eccezione. Mi sto perdendo qualcosa? Il modello Arrange, Act, Assert non è adatto quando si usano i banchi rigorosi? C'è un modo più semantico per impaginare questi test?TDD Arrange Act Assert pattern quando si usano i Mock per verificare le chiamate di dipendenza

Un banale esempio costituito da ...

[TestClass] 
public void DeleteUser_ShouldCallDeleteOnRepository() 
{ 
    // Arrange 
    var userRepository = new Mock<IUserRepository>(MockBehavior.Strict); 

    int userId = 9; 
    userRepository.Setup(x => x.Delete(userId)); 

    var controller = new UserController(userRepository.Object); 

    // Act 
    controller.DeleteUser(userId); 

    // Assert 
    // ...? 
} 
+0

Cosa succede se il test come scritto non riesce (Repository.delete() non viene chiamato)? Il messaggio di errore è chiaro? Se è così, direi che non è necessario cambiarlo. –

risposta

22

tuo finto sta prendendo il posto di un collaboratore. L'hotel è idealmente facendo una delle due cose:

  • fornire informazioni o dati
  • facendo un lavoro

Quando il finto è fornire informazioni o dati, è sufficiente che questo dovrebbe essere un stub. È possibile impostare il valore di ritorno della simulazione alle informazioni richieste. Questo dovrebbe essere parte di Disponi.

Quando la simulazione sta facendo un lavoro, la delega può essere verificata. Questo è il motivo per cui hai Assert.

Quello che stai facendo con l'interazione rigorosa è garantire che ogni singola interazione è prevista, in sostanza dicendo: "Ecco cosa mi aspetto che accada, e se succede qualcos'altro è sbagliato." Questo è un tipo diverso di test per Agire, Disponi, Assert, che dice: "In questo contesto, quando faccio queste cose, dovrei ottenere questo risultato".

Con una "bella" simulazione, devi solo preoccuparti delle interazioni a cui sei interessato. Quindi, ad esempio, se sono un controller e sto cercando alcune informazioni in un repository, convalidandolo con un validatore, quindi salvare il risultato in un altro repository, potrei avere diversi test:

  • uno per verificare che sto convalidando contro le giuste informazioni
  • uno per controllare come sto rispondendo alle convalida non corretta
  • e uno per verificare che io salvi l'oggetto.

Con la stretta finta, si hanno a che fare tutti le aspettative, anche se tutto quello che ti interessa è il "salvataggio". Usando un bel finto, possiamo dividere i diversi aspetti del comportamento e concentrarci solo su uno di essi in ciascun test.

Come bonus aggiuntivo, curato deride permettono di fare:

  • dato un contesto
  • Quando questo evento si verifica
  • Allora questo risultato dovrebbe avvenire

Mentre deride severe fanno you do:

  • Dato un contesto
  • Aspettatevi alcune cose accada
  • Quando si esegue un evento
  • Poi vai indietro e leggere ciò che il risultato avrebbe dovuto effettivamente.

Il primo di questi è generalmente considerato più leggibile.

+1

Ok, interessante. Per essere sicuro di aver capito bene, stai promuovendo di non usare 'MockBehavior.Strict' ma usando la verifica esplicita invece? – fearofawhackplanet

+2

Sì, questo è quello che vorrei sostenere (ed è il motivo per cui sono stati creati i "bei" schemi di derisione come Moq). Nota che avrai ancora bisogno di impostare dei mock che forniscano informazioni - ma la cosa bella è che ora puoi farlo * se vengono chiamati o meno *. – Lunivore

+1

+1 per una risposta chiara e persuasiva. –

Problemi correlati