È possibile acquisire oggetti java per salvarli come risorse di test?

2

Sto scrivendo test unitari per verificare che per determinate risposte del database, alcuni oggetti siano creati / fatti.

Il problema che ho, è che quando mocking la risposta del database, devo passare manualmente e definire il comportamento esatto che risponderà database / database accessor, per ogni test.

Cosa sarebbe molto più semplice, sarebbe se eseguissi determinate query sul database di produzione e catturassi gli oggetti restituiti e li salvassi come risorsa di test, e li usassi come i miei oggetti da restituire dal mio database deriso.

Se gli oggetti in questione implementassero Serializable , questo sarebbe piuttosto semplice in quanto potrei semplicemente salvarli come testo.

Ma cosa succede se non implementano Serializable ? In quale altro modo posso acquisire oggetti java per il test?

    
posta dwjohnston 14.04.2016 - 03:53
fonte

4 risposte

5

Hai già catturato il nocciolo della tua domanda: un oggetto non% Serializable può essere difficile da deridere nel modo in cui descrivi .

Quello che stai cercando di fare è meno di un test unitario e più di un test di sistema. puoi implementarlo come test unitario (ad es. JUnit) ma non sarà efficiente.

Sembra che tu stia essenzialmente provando a testare l'unità usando veri DAO di qualche tipo.

  1. Crea un processo per inizializzare un semplice database in uno stato conosciuto. Questo potrebbe essere qualsiasi cosa, dal ripristino di un vero (ma piccolo) backup di un DBMS "reale" come Oracle o SQL Server o un'istantanea di un database Sqlite.
  2. Inizializza il test connettendosi al database.
  3. Esegui il test ottenendo dati dal DB come oggetto Java (ad esempio DAO) e facendo tutto ciò che devi fare.
  4. Elimina il DB: il prossimo test viene reinizializzato in modo che i test non interferiscano tra loro.

Potrebbero esserci anche strutture fittizie nel livello di astrazione DB (ad esempio Hibernate), ma non l'ho esaminato di recente. Se stai usando JDBC direttamente allora buona fortuna: si tratta di un protocollo di basso livello che non affronta problemi come i database di test unitari.

    
risposta data 14.04.2016 - 05:31
fonte
2

Ci sono molti modi per farlo.

Quello che più assomiglia alla tua configurazione di produzione sarebbe utilizzare un database in memoria come H2 e plug nel tuo sistema durante il test. Quindi puoi semplicemente esportare le righe in questione e iniziare il test con l'importazione di un gruppo di righe. H2 può essere eseguito in "modalità MySQL" se stai usando MySQL; questo lo rende principalmente compatibile con MySQL, almeno per le dichiarazioni di base. Non è compatibile al 100% come ad es. scappare funziona diversamente. Ma una volta capito questo non devi farlo di nuovo. Se si tratta solo di tipi di dati un po 'standard e di query semplici, direi che questa è l'opzione migliore, in quanto tutto ciò che si deve prendere in giro è l'origine dati. Preferisco percorrere questa strada per questo motivo. Funziona bene con JDBC diretto o con alcuni livelli di astrazione come Spring JDBC e Hibernate.

Un'altra pratica comune è serializzare i tuoi oggetti in JSON, utilizzando il parser di Jackson ad esempio, soprattutto, poiché molto di applicazioni si stanno già occupando di JSON e i serializzatori / deserializzatori sono prontamente disponibili. Jackson può serializzare oggetti in JSON anche se non sono serializzabili, purché seguano la specifica dei bean Java. Deriva i nomi delle proprietà ispezionando la classe. Lo svantaggio è che devi prendere in giro il tuo DAO, non solo cambiare l'origine dati. Puoi semplicemente copiare & incollare gli oggetti serializzati nel test o leggere da un file e quindi deserializzare. Ci sono molti moduli disponibili per i tipi non standard e puoi anche scrivere i tuoi serializzatori.

    
risposta data 23.04.2016 - 05:16
fonte
1

Ho salvato dal vivo, istanziato oggetti con stato in un file binario e poi li ho riportati in vita, semplicemente aggiungendo acqua come le scimmie marine, l'unica avvertenza è che tutti gli oggetti devono implementare serializzabili:

public static void saveObjects(Animal a, Car b, Thing c, String filePath) throws FileNotFoundException, IOException{
    FileOutputStream fos = new FileOutputStream(filePath);
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.writeObject(a);
    oos.writeObject(a);
    oos.writeObject(c);
}
public static Object[] loadObjects(String filePath) throws FileNotFoundException, IOException, ClassNotFoundException{
    FileInputStream fis = new FileInputStream(filePath);
    ObjectInputStream ois = new ObjectInputStream(fis);
    Object o[] = new Object[3];
    o[0] = ois.readObject();
    o[1] = ois.readObject();
    o[2] = ois.readObject();
    return o;
}
risposta data 29.06.2017 - 01:13
fonte
0

Per Java, una soluzione potrebbe essere uno strumento di riproduzione-riproduzione come testrecorder . La versione corrente ti consentirà di annotare i metodi di interesse con @Recorded :

  • facendo in modo che catturi tutti i dati in arrivo o in partenza da questo metodo (argomenti, risultati, eccezioni, questo puntatore)
  • traduzione di questi dati in test di unità eseguibili

Ci sono altri strumenti come questo (reCrash, Jthor) per scopi speciali.

    
risposta data 29.06.2017 - 00:44
fonte

Leggi altre domande sui tag