2012-11-14 13 views
7

Sto scrivendo una semplice applicazione che leggerà alcuni record e li inserirà in un database. Ho scritto una stored procedure che gestisce la logica di inserimento e ho pianificato di testarla separatamente. Ora mi piacerebbe scrivere un buon test unitario per la parte della logica che prende un oggetto business e lo passa alla chiamata della procedura memorizzata.Come si deve testare l'unità Java che chiama una procedura memorizzata MySQL?

ho penso quello che voglio fare è passare un mock della connessione al database, quindi affermare che la chiamata viene effettuata con i valori dei parametri previsti:

Connection dbConnection = makeMockConnection(); // how? 
MyObjectWriter writer = new MyObjectWriter(dbConnection); 
writer.write(someSampleObject); 
// somehow assert that dbConnection called 
// `sp_saveMyObject` with param values x, y, and z 

Tuttavia, sembra come un sacco di lavoro scavare all'interno di java.sql.Connection, capire come funziona, quindi prendere in giro tutti i risultati. C'è una libreria di test che fa tutto questo per me? Sto arrivando a questo nel modo sbagliato?

+0

Mocking della connessione per verificare se un metodo viene chiamato è davvero semplice. Dovresti avere familiarità con [Mockito] (http://code.google.com/p/mockito/) – Kai

+0

Sto cercando di evitare di limitare la logica di business ad eseguire un determinato modo: potrei chiamare 'Connection.createStatement' oppure 'Connection.prepareStatement' o' Connection.prepareCall' o anche 'Connection.nativeSql', ognuno dei quali è * corretto * (in quanto i dati vengono passati alla procedura). Sto cercando di evitare di dover prendere in giro * tutte * di quelle cose, o almeno di dover scrivere quelle stesse canzonature. – Coderer

risposta

2

È possibile creare un database HSSQL in memoria con una procedura memorizzata fittizia. Il motto sproc avrebbe inserito una riga in una tabella per mostrare che era in esecuzione e quali erano i suoi parametri. Esegui il codice sotto test e poi guarda nel db per vedere cosa è successo.

+0

Quanto sovraccarico viene creato durante i test in esecuzione? In questo momento il resto dei miei test può essere eseguito in pochi millisecondi: il tempo di standup/teardown è significativo? – Coderer

+1

Non l'ho mai cronometrato, ma indovinerei qualche decimo di ms a causa dei file temporanei che crea. Se tu avessi solo una manciata di questi test di tipo non ti preoccupare. Se ne avessi migliaia potresti. È sempre possibile condividere la stessa istanza db su un numero di test purché si pulisca la tabella tra di essi. Io uso in memoria dbs per testare un sacco di cose e trovare la semplicità che la vittoria supera di gran lunga il tempo di esecuzione. Non è necessario modificare alcun codice semplicemente passare una stringa di connessione jdbc diversa. questo è un enorme vantaggio. – AutomatedMike

+0

Sto avendo un po 'di problemi a trovare una semplice guida per iniziare: la documentazione HSQLDB è di centinaia di pagine e la maggior parte dei post del blog, ecc., Che posso trovare sui test unitari con HSQLDB sono specifici per Ibernazione/Primavera. Ho solo bisogno di avviare un database, aggiungere una tabella e una procedura memorizzata, quindi strapparlo quando ho finito. Dovrebbe essere facile, giusto? – Coderer

0

È possibile utilizzare il modello di progettazione Decorator per il collegamento mocking. Si crea una connessione reale al DB con il driver che si utilizza, che è racchiuso dalla classe ConnectionImpl che implementa l'interfaccia di connessione e mantiene la connessione reale come membro.
Ogni chiamata reale che non si vuole effettivamente fare, sostituirla con un codice simulato, e ogni chiamata i soggiorni chiama lo stesso metodo dell'oggetto di connessione reale (Delegare la chiamata).
In questo modo si sta codificando come al solito, differiscono solo nell'oggetto restituito dal metodo che crea la connessione.
Ora, nell'oggetto mock (il tuo ConnectionImpl) è possibile aggiungere un codice di test dell'unità che controlla l'input, ad esempio.

+0

Il problema qui è che, come dico nel mio commento sull'OP, sto cercando di non scavare nelle viscere della Connection. Il wrapper dovrebbe sapere * cosa * controllare, quale punto nell'esecuzione è comune tra i 4 o 5 modi diversi di realizzare la stessa cosa. Via, molto più lavoro rispetto alla risposta di @ AutomatedMike. – Coderer

0

Se non si è interessati a come funziona MyObjectWriter, basta che lo faccia, quindi sarei propenso a scrivere un test di integrazione e dimenticare un test unitario.

Tu non parlare di come si sta testando la stored procedure, così mi perdoni, ma quello che vorrei fare è scrivere i test in tutto MyObjectWriter che invocano la-stored procedure in un database e quindi verificare lo stato del database in seguito. Userei un database in memoria, se possibile, per mantenere basse le durate del test.

Problemi correlati