2010-03-20 11 views
5

Uso VS2008 per il targeting di .NET 2.0 Framework e, nel caso, no non posso modificare questo :)Come può essere modificata la "data odierna" ai fini del test unitario?

Ho una classe DateCalculator. Il metodo GetNextExpirationDate tenta di determinare la scadenza successiva, utilizzando internamente DateTime.Today come data di riferimento.

Mentre stavo scrivendo i test di unità, mi sono reso conto che volevo testare GetNextExpirationDate per le diverse date "oggi".

Qual è il modo migliore per farlo? Ecco alcune alternative che ho preso in considerazione:

  • Esporre una proprietà/metodo sovraccarico con argomento baselineDate e utilizzarlo solo dal test dell'unità. Nel codice client effettivo, ignorare il metodo property/overloaded in favore del metodo che imposta automaticamente baselineDate in DateTime.Today. Sono riluttante a farlo poiché rende l'interfaccia pubblica della classe DateCalculator scomoda.
  • Creare un campo protetto denominato baselineDate impostato internamente su DateTime.Today. Quando si esegue il test, derivare un e impostare baslineDate tramite il costruttore. Mantiene l'interfaccia pubblica pulita, ma non è ancora eccezionale - baselineDate è stato reso protetto e una classe derivata è richiesta, sia per il solo test.
  • Utilizzare i metodi di estensione. Ho provato questo dopo aver aggiunto il ExtensionAttribute, quindi ho capito che non avrebbe funzionato perché i metodi di estensione non possono accedere a variabili private/protette. Inizialmente pensavo che questa fosse una soluzione davvero piuttosto elegante. :(

Sarei interessato a sentire quello che pensano gli altri.

+0

Buona domanda ... che sarebbe stato divertente per aspettare fino a una data specifica per la ricerca di un test in mancanza, perché si basano su ciò che 'oggi' è e non può incrementarlo :) – slugster

+0

Duplicate: http: //stackoverflow.com/questions/2425721/unit-testing-datetime-now –

+0

Grazie per tutti gli input. Anche l'approccio del fornitore di data e ora era qualcosa su cui avrei dovuto pensare. In questo caso, comunque, penso che andrò con l'approccio di Gishu - sembra essere il minimo lavoro e meno invasivo per me. –

risposta

1

Solitamente raccolgo le chiamate al sistema operativo all'interno di un'astrazione/interfaccia in modo che possa facilmente testarlo .. Proprio come Andrew come detto sopra.

Tuttavia, viene data solo la necessità menzionata nella domanda; Ritengo che "Sottoclasse e Override" sia il modo più semplice e meno invasivo per ottenere questo risultato - Opzione 2 menzionata dall'OP.

public class DateCalculator 
{ 
    public DateTime GetNextExpirationDate() { // call to GetBaseLineDate() to determine result } 
    virtual protected GetBaseLineDate() { return DateTime.Today; } 
} 

// in your test assembly 
public class DateCalcWithSettableBaseLine : DateCalculator 
{ 
    public DateTime BaseLine { get; set;} 
    override protected GetBaseLineDate() 
    { return this.BaseLine; } 
} 
4

È possibile utilizzare un'interfaccia che fornisce la data di riferimento. Normalmente si usa un'implementazione che restituisce DateTime.Today ma a scopo di test hanno uno che permette il test di unità forniscono una data.

Questo potrebbe anche essere utile se si rende necessario utilizzare la data corrente sul server datebase o qualche altra macchina che non è necessariamente dove il codice è in esecuzione.

In effetti, ecco la stessa domanda con alcune risposte più dettagliate rispetto miniera: Unit Testing: DateTime.Now

1

Una possibilità è quella di creare un sovraccarico interno che prende un DateTime, e delegare l'effettiva attuazione a quella:

public DateTime GetNextExpirationDate() 
{ 
    return GetNextExpirationDate(DateTime.Today); 
} 

internal DateTime GetNextExpirationDate(DateTime after) 
{ 
    // implementation goes here 
} 

È quindi possibile utilizzare InternalsVisibleToAttribute per fare il sovraccarico visibile all'assembly di test e l'assembly di test può quindi chiamarlo con i valori DateTime di sua scelta.

0

È possibile modificare l'orologio dell'ora del sistema operativo sul computer che sta eseguendo il test. Questo è facile e trasparente, ma fai attenzione ai problemi con i timestamp dei file.

Problemi correlati