Come scrivere un test unitario per un metodo di repository che restituisce alcuni dati, in cui i dati possono cambiare nel tempo?

2

Ho un codice che legge cinque numeri da un database:

class Repository extends DatabaseRepository
{
    function getCoefficients(string $model)
    {
        return $this->getDatabaseLink()->query("
            select a, b, c, d, e from coefficients 
            where model = ? and active = 1
        ", $model)->getSingleResult();
    }
}

Chiamando il metodo sopra restituisce qualcosa del genere:

array (
  'a' => '0.0001',
  'b' => '0.001',
  'c' => '0.01',
  'd' => '0.1',
  'e' => '1.0'
)

I numeri restituiti possono cambiare nel tempo, in base a quale particolare record è active in qualsiasi momento.

Come faccio a scrivere un test unitario per questo? Dovrei scriverne uno? Per cosa cerco? Per evitare di trattare con il database live, posso prendere in giro il database, ma poi cosa testerò davvero?

Quello che ho ora

Per ora sono andato avanti e ho scritto un test, che impegna un database live e verifica i numeri esatti che vengono restituiti, ma quel test si interromperà non appena i dati rilevanti cambiano nel database o se l'implementazione del database cambia (dal mio test deve chiamare e impostare il database live).

Domande specifiche

  • Che cosa dovrei provare a livello di repository?
  • Come posso gestire il fatto che i dati restituiti dal database live possono cambiare?
  • Si dovrebbe scrivere un test unitario per questo codice?
posta Dennis 22.12.2017 - 17:53
fonte

4 risposte

7

Se l'intero scopo di un metodo è quello di ottenere alcuni dati da un database, è ovviamente inutile scrivere un test automatico per il metodo che deride il database, che ostacolerebbe l'intero scopo del test.

Inoltre, raramente ha senso scrivere test su un sistema di produzione. Gli ambienti di prova e gli ambienti di produzione devono sempre essere separati per vari motivi . Quindi è meglio impostare un database di test, con dati stabili al suo interno, quindi il problema scompare.

Alcune osservazioni ai tuoi commenti:

  • se non si utilizza un sistema DB leggero, l'impostazione di un database di test solo per alcuni test potrebbe non valerne la pena. Tuttavia, nei sistemi DB più grandi è possibile implementare diversi schemi e aree dati affiancati, basta rendere lo schema un parametro del repository e implementare un'area di test stabile nel database di sviluppo

  • se l'intero codice è ancora in flusso, il test per i risultati esatti potrebbe semplicemente essere troppo presto. Tuttavia, potrebbe essere sensato testare cose come la connessione db funzionante, se la sintassi SQL è corretta o se la query fornisce un numero minimo di record. Se questa è la tua situazione, prova esattamente questo.

risposta data 22.12.2017 - 18:20
fonte
2

Should a unit test be written for this code at all?

No, perché i test delle unità devono essere eseguiti in totale isolamento e testare la logica all'interno del metodo. Invece, scrivi un test automatico.

What should I be testing for in a Repository level?

Il test automatico può:

  • Inserisci programmaticamente alcuni dati nella tua istanza db TEST ;
  • Chiama il codice del tuo deposito;
  • Asserisci sui dati recuperati.

How do I deal with the fact that data returned by live database can change?

Stessa risposta di cui sopra.

    
risposta data 22.12.2017 - 20:50
fonte
2

Hai un metodo setCoefficients() ? Se è così, quello che preferisco fare è questo. (Attenzione: è controverso, i miei punti potrebbero soffrire ...)

  1. Cancella il db TEST
  2. Inserisci i dati utilizzando il tuo codice.
  3. Recupera e confronta.

Questo non è un "test unitario" . Ma nemmeno le altre risposte. Questo prova quello che (di solito) vuoi veramente sapere: che quello che scrivi è ciò che leggi. E dovresti aggiungere test a questi casi di errore, ad es. un modello fasullo nel tuo codice, sono gestiti. Ti interessa davvero se i dati sono in un db SQL con colonne denominate a, b, c ...? Solitamente non .

    
risposta data 23.12.2017 - 08:03
fonte
0

Oltre alle altre risposte, potrebbe essere una buona idea interrompere il test in più parti. Invece di testare semplicemente il comportamento molto ampio della persistenza di un oggetto, sarebbe meglio testare le singole cose come il modo in cui l'oggetto viene convertito in dati e la parte di connessione con il database.

    
risposta data 23.12.2017 - 10:26
fonte

Leggi altre domande sui tag