I have a process that runs in a thread (used as a realtime signal analysis process). I want to feed that thread process a known input, and then test — in jUnit — that the output is correct. I have a callback listener that can notify me when the thread finishes processing the data and I can run assertions on the result successfully by registering the test case itself as a listener.
When those assertions fail, they do throw an exception. But that exception is not registered as a failure by jUnit, presumably because they are happening outside of a test method.
How do I structure my jUnit test so that the test fails correctly after the listener returns? Here’s a simplified version of the code.
public class PitchDetectionTest extends TestCase
implements EngineRunCompleteListener() {
AudioData fixtureData;
PitchDetectionEngine pitchEngine;
public void setUp() {
fixtureData = <stuff to load audio data>;
}
public void testCorrectPitch() {
pitchEngine = new PitchEngine(fixtureData);
pitchEngine.setCompletionListener(this);
pitchEngine.start();
// delay termination long enough for the engine to complete
try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
}
// gets called by the PitchEngine when it has finished processing all data in the
// fixtureData. This is the only method defined by interface
// EngineRunCompleteListener.
public void notifyEngineRunComplete() {
// The real code asserts things about the PitchEngine's results. When they fail,
// an exception is thrown that I can see in the console, but this unit test still
// shows as 'success' in the jUnit interface. What I want is to see
// testCorrectPitch() fail.
assertTrue(false);
}
}
public class PitchEngine () {
EngineRunCompleteListener completionListener();
Thread myThread;
public void start() {
// other stuff
myThread = new Thread(this);
myThread.start();
}
public void run() {
while (some condition) {
// do stuff with the data
}
if (engineRunCompleteListener != null) {
engineRunCompleteListener.notifyEngineRunComplete();
}
}
}
You already have two threads running. Your junit thread, and the process thread (started by
myThread.start().Off the top of my head, I can think of at least two options that you have, all of them involving moving the assertion away from
notifyEngineRunComplete. For example:jointo wait for the process thread to finish, and then do your assertions (Javadoc here).Executorand aFutureobject. I think this would be the coolest solution if it works with your classes (Javadoc here).