Problemi con TDD nella progettazione di servizi / depositi

3

Scenario: vogliamo test drive un metodo di creazione, il metodo risultante sarebbe simile a questo:

public MyModel Create(MyModel model){
    var dao = TransformToDao(model);
    dao.Date = DateTime.Now;
    var result = _repository.Create(dao);
    return TranformToModel(result);
}

Penso che due punti di prova per questo metodo dovrebbero essere:

  1. Crea dovrebbe impostare una data sull'ora corrente
  2. Crea dovrebbe creare (salvare) il modello

Ma vedo alcuni problemi qui. Il metodo ha un output, ma qui la funzionalità non è impostare la data, ma piuttosto salvare con la data impostata, quindi il controllo dell'output non sembra il giusto pensare di fare. Ad esempio, questo metodo supererebbe anche il test:

public MyModel Create(MyModel model){
    var dao = TransformToDao(model);
    var result = _repository.Create(dao);
    var model = TranformToModel(result);
    model.Date = DateTime.Now;
    return model;
}

Se voglio guidare la funzionalità di creazione (salvataggio) ho bisogno di simulare il repository, ma poi sto dettando un'implementazione particolare. Devo simulare il repository e controllare se è stato chiamato con dao, che ha impostato DateTime?

_repository.AssertWasCalled(c => c.Create(Arg<MyDao>.Matches(x => (int) (x.Date - DateTime.Now).TotalSeconds == 0)));

Questo porta a test come questo:

public MyModel Update(MyModel model){
    return _repository.Update(model);
}

[Test]
public void UpdateShouldCallRepositoryUpdate(){
   var model = new MyModel();
   _repository.Expect(x => x.Update(model)).Return(model);

   _service.Update();

   _repository.AssertWasCalled(x => x.Update(model));
}

Questo tipo di test mi sembra molto ridondante, ma forse è il modo di farlo? O forse c'è qualche tipo di problema nell'architettura o nei test?

    
posta Perpetuum 31.01.2017 - 11:08
fonte

1 risposta

2

Ecco come è fatto. Si assicura che se qualcuno dovesse rimuovere quella linea dal tuo codice in futuro, il test fallirebbe. Infatti, se si utilizza TDD, è necessario scrivere quel test prima di scrivere l'implementazione. Mi piacerebbe solo che il tuo _repository fosse un'interfaccia, invece di un'implementazione reale, e come Nkosi ha accennato, potresti voler iniettare anche un ITimeService (con membro GetCurrentTime ()), invece di dipendere direttamente da DateTime.Ora.

    
risposta data 02.02.2017 - 13:48
fonte

Leggi altre domande sui tag