Continuo a provare questo tipo di codice (lingua irrilevante):
public class Foo() {
public Foo(IDependency1 dep1) {
this.dep1 = dep1;
}
public void setUpListeners() {
this.dep1.addSomeEventListener(.... some listener code ...);
}
}
Tipicamente, vuoi testare cosa succede quando la dipendenza fa scattare l'evento, la classe sotto test reagisce in modo appropriato (in alcuni casi, lo scopo solo di tali classi è di collegare molti altri componenti, che può essere testato indipendentemente.
Finora, per verificarlo, finisco sempre per fare qualcosa del tipo:
- creando uno "stub" che implementa sia un
addXXXXListener
, che semplicemente memorizza il callback, sia unfireXXXX
, che chiama semplicemente qualsiasi listener registrato. Questo è un po 'noioso dal momento che devi creare il mock con l'interfaccia giusta, ma ciò può fare - usa un framework introspettivo che può 'spiare' su un metodo e iniettare la vera dipendenza nei test
C'è un modo più pulito per fare questo genere di cose?
EDIT: per chiarire cosa intendo, il mio problema è che se potessi scrivere qualcosa del genere:
public class FooTest() {
public void testListensToDependencies() {
IDependency mockDependency = createMock(IDependency.class)
Foo tested = new Foo(mockDependency);
tested.setUpListeners();
expect(mockDependency.addSomeEventListener).toHaveBeenCalled();
}
}
Tuttavia, ovviamente questo test dovrebbe passare indipendentemente da ciò che fa l'ascoltatore . Questo mi preoccupa, dal momento che voglio testare che sto collegando i miei oggetti per fare la cosa giusta.
La prossima cosa migliore sarebbe:
public class Foo () {
public Foo(IDependency1 deps) { .... }
public void setUpListeners() {
// In a language with first class function :
this.dep1.addSomeEventListener(this.handleSomeEvent);
// In a language without it :
this.dep1.addSomeEventListener(new Foo.SomeEventHandler());
}
E poi scriverei test per:
-
controlla che 'addSomeEventListener' sia stato chiamato sia con la funzione del gestore di destra, sia con un'istanza della classe del gestore di eventi di destra
-
controlla che la funzione del gestore o la classe del gestore eventi implementino effettivamente il comportamento previsto.
Ora non sono sicuro che sarebbe più chiaro, o se è il segno che sto collegando i miei oggetti nel posto sbagliato ...