Assertion Inside Thread/Runnable run()
ID |
java.junit_assertion_in_run_method |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Java |
Tags |
reliability, testing |
Description
Reports a test-assertion call made directly inside the run() method of a class extending Thread or implementing Runnable. A run(int) overload, or any other signature, is not the contract the framework invokes off-thread and is left alone.
Rationale
Starting a Thread (or handing a Runnable to one) runs its run() method on a separate worker thread. A JUnit or AssertJ assertion failing there throws an AssertionError that terminates the worker thread — it never reaches the thread that is actually running the test, so the test method returns normally and reports as passed no matter what the assertion found.
class BackgroundWorker extends Thread {
@Override
public void run() {
Assert.assertEquals(1, computeTotal()); // failure here never fails the test
}
}
Remediation
Run the logic on the test’s own thread — call the method directly instead of starting a separate thread — or move the assertion out of run() and check the worker’s result from the test thread once it finishes.
class BackgroundWorker extends Thread {
@Override
public void run() {
result = computeTotal();
}
int result;
}
// in the test:
BackgroundWorker worker = new BackgroundWorker();
worker.run(); // executes on the test thread
Assert.assertEquals(1, worker.result);