I have a class that implements Runnable
called DoThingInALoop
. It is given to a second class that will create a thread out of it, call this thread Boss
. The Boss
can tell the runnable to quit and let the thread terminate. Later, it can create a new thread with that same DoThingInALoop
.
When I am writing unit tests for the Boss
I want to mock the DoThingInALoop
because it is not the object under test. However, DoThingInALoop
extends a class Loop
and the code for Loop
is actually being executed in the thread spawned by the Boss
. That code of course runs into NullPointerException
s because none of the member variables are set, because the object is mocked.
How can I prevent Java's Thread
from "seeing through" the mock?
public class Loop implements Runnable {
private final Object member = new Object();
public void run() {
// This code runs, but it shouldn't
synchronized (member) { // Throws NPE
...
}
}
public class DoThingInALoop extends Loop {
public void stopDoingThingsInALoop() {
// Set instance member that on next loop iteration signals thread to return
}
}
public class Boss {
private final DoThingsInALoop toBeMocked;
public Boss(final DoThingsInALoop toBeMocked) {
this.toBeMocked = toBeMocked;
}
public void start() {
// Simplified
new Thread(toBeMocked).start();
}
public void stop() {
toBeMocked.stopDoingThingsInALoop();
}
}
public class TestClass {
@Test
public void aTest() {
// Setup Mocks
DoThingsInALoop mockLoop = mock(DoThingsInALoop.class);
Boss boss = new Boss(mockLoop);
// Run test
boss.start();
// After the above line runs, a new thread is started and
// the run() method of `Loop` executes until the NPE
// is hit when it attempts to access a member variable
// which is of course not set because it is a mocked object
...
}
}
Aucun commentaire:
Enregistrer un commentaire