thebol
07-01-2007, 13:41
Ho provato a introdurre il TDD dove lavoro in piccoli componenti che dovevo modificare e per semplicità ( :asd: ) ho rifatto da zero. Questi componenti vengono usati da delle action di struts(per chi non le conosce delle servlet), e devono accedere a DB.
Si è posto il problema come usare l'accesso a db nei test. Ho deciso di Mockare l'accesso al db, e fin qua + o - tutto chiaro(anche se la soluzione non mi soddisfaceva + di tanto, forse sarebbe piu semplice un db in memory fatto apposta per i test...).
Però è sorto un problema. Dentro il componente creavo la connesione a db, cioè un oggetto(new DBConnect(...) ).
Problema:
Visto che io devo testare il componente, e questo crea l'oggetto che rappresenta la connesione al db, come faccio a dirgli di usare la connesione fake?
Naturalmente si può passare la connesione al componente come parametro(in creazione, o nel metodo che fa il lavoro).
Ma questo vuol dire che per testare un componente in pure isolation, questo non deve creare oggetti(o almeno oggetti che ne possono alterare il funzionamento, e che si prestano a essere mockati).
Questo crea problemi ad esempio, quando io voglio testare la action che usa il mio componente. La action ha la particolarità di essere chiamata dall'application server, percui non posso alterarne i parametri di creazione(a meno di fare cambiamenti strutturali che coinvolgerebbero tutte le action dell'applicazione)
In questo caso le soluzioni sarebbero 2:
La action usa il mio componente in una certa maniera, io mocko il mio componente e verifico che vengano effetuate le giuste chiamate con i giusti parametri. Questo non si può fare perchè il componente viene creato all'interno della action.
Oppure:
Mocko il db, e lo passo al mio componente. Non posso perchè la connesione al db o la crea il mio componente(che non posso mockare), oppure la passa la action al mio componente.Ma sto testando la action, e come faccio a dirgli di passare il db mockato invece di quello reale?
Il mock è percio molto utile quando qualcosa di complesso (il db, l'accesso ai file, alla rete, etc) viene passato a un componente, ma viene meno utile quando questo viene usato.
Certo nel mio esempio, si sarebbe potuto ristrutturare il meccansimo delle action, in modo da fare una action personalizzata a cui passare la connesione al db. Però nel mio caso era impossibile stando io testando solo una piccola parte dell'applicazione.
Tutto questo discorso per chiedervi o sentire opinioni sui mock, o meglio, su questa presunta (da me) limitiazione dei mock.
ps. Nel applicazione reale in un punto ho risolto il problema grazie al fatto che si usavano dei singletone. C'era un associazione stringa-> Classe per la connesione. Ho sostiutito la classe base, con quella mockata e ho risolto. Però in un altro punto non ci sono riuscito :|
pps so che il post è contorto, spero che qualcuno lo capisca :asd:
Si è posto il problema come usare l'accesso a db nei test. Ho deciso di Mockare l'accesso al db, e fin qua + o - tutto chiaro(anche se la soluzione non mi soddisfaceva + di tanto, forse sarebbe piu semplice un db in memory fatto apposta per i test...).
Però è sorto un problema. Dentro il componente creavo la connesione a db, cioè un oggetto(new DBConnect(...) ).
Problema:
Visto che io devo testare il componente, e questo crea l'oggetto che rappresenta la connesione al db, come faccio a dirgli di usare la connesione fake?
Naturalmente si può passare la connesione al componente come parametro(in creazione, o nel metodo che fa il lavoro).
Ma questo vuol dire che per testare un componente in pure isolation, questo non deve creare oggetti(o almeno oggetti che ne possono alterare il funzionamento, e che si prestano a essere mockati).
Questo crea problemi ad esempio, quando io voglio testare la action che usa il mio componente. La action ha la particolarità di essere chiamata dall'application server, percui non posso alterarne i parametri di creazione(a meno di fare cambiamenti strutturali che coinvolgerebbero tutte le action dell'applicazione)
In questo caso le soluzioni sarebbero 2:
La action usa il mio componente in una certa maniera, io mocko il mio componente e verifico che vengano effetuate le giuste chiamate con i giusti parametri. Questo non si può fare perchè il componente viene creato all'interno della action.
Oppure:
Mocko il db, e lo passo al mio componente. Non posso perchè la connesione al db o la crea il mio componente(che non posso mockare), oppure la passa la action al mio componente.Ma sto testando la action, e come faccio a dirgli di passare il db mockato invece di quello reale?
Il mock è percio molto utile quando qualcosa di complesso (il db, l'accesso ai file, alla rete, etc) viene passato a un componente, ma viene meno utile quando questo viene usato.
Certo nel mio esempio, si sarebbe potuto ristrutturare il meccansimo delle action, in modo da fare una action personalizzata a cui passare la connesione al db. Però nel mio caso era impossibile stando io testando solo una piccola parte dell'applicazione.
Tutto questo discorso per chiedervi o sentire opinioni sui mock, o meglio, su questa presunta (da me) limitiazione dei mock.
ps. Nel applicazione reale in un punto ho risolto il problema grazie al fatto che si usavano dei singletone. C'era un associazione stringa-> Classe per la connesione. Ho sostiutito la classe base, con quella mockata e ho risolto. Però in un altro punto non ci sono riuscito :|
pps so che il post è contorto, spero che qualcuno lo capisca :asd: