I keep getting to test this kind of code (language irrelevant) :
public class Foo() {
public Foo(IDependency1 dep1) {
this.dep1 = dep1;
}
public void setUpListeners() {
this.dep1.addSomeEventListener(.... some listener code ...);
}
}
Typically, you want to test what when the dependency fires the event, the class under tests reacts appropriately (in some situation, the only purpose of such classes is to wire lots of other components, that can be independently tested.
So far, to test this, I always end up doing something like :
- creating a 'stub' that implements both a
addXXXXListener
, that simply stores the callback, and afireXXXX
, that simply calls any registered listener. This is a bit tedious since you have to create the mock with the right interface, but that can do - use an introspective framework that can 'spy' on a method, and inject the real dependency in tests
Is there a cleaner way to do this kind of things ?
EDIT : to clarify what I mean, my trouble is that if I could write something like this :
public class FooTest() {
public void testListensToDependencies() {
IDependency mockDependency = createMock(IDependency.class)
Foo tested = new Foo(mockDependency);
tested.setUpListeners();
expect(mockDependency.addSomeEventListener).toHaveBeenCalled();
}
}
However, obviously this test would pass no matter what the listener does. This is troubling me, since I want to test that I am wiring my objects to do the proper thing.
The next best thing would be :
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());
}
And then I would write tests to :
check that the 'addSomeEventListener' was called either with the right handler function, or with an instance of the right event handler class
check that the handler function, or the event handler class, actually implement the expected behavior.
Now I am not sure if that would be clearer, or if it is the sign I'm wiring my objects at the wrong place....