At work, we use JMockit. I’m far more comfortable with Mockito, which made it very easy for me to understand how to capture a Runnable passed in, execute it, and then check that certain calls were made. I have always struggled with doing that with JMockit, but I think I finally figured it out:
public class DemoWithRunnable {
public interface Dependency {
int someMethod();
void otherMethod(int i);
}
private final Dependency dependency;
private final ExecutorService executor;
public DemoWithRunnable(Dependency d, ExecutorService e) {
this.dependency = d;
this.executor = e;
}
public void doSomething() {
executor.submit(new Runnable() {
public void run() {
int i = dependency.someMethod();
dependency.otherMethod(i);
}
});
}
}
What I want to do here in a test, of course, is:
- Check that we call ExecutorService.submit
- Run the Runnable that was passed to submit
- Mock someMethod and return some value, and
- Check that otherMethod was called with the returned value.
And I think this is how you do it in JMockit:
public class DemoWithRunnableTest {
@Mocked DemoWithRunnable.Dependency d;
@Mocked ExecutorService e;
@Test
public void testDoSomething() {
DemoWithRunnable impl = new DemoWithRunnable(d, e);
impl.doSomething();
List
// capture the Runnable
new Verifications() {{
e.submit(withCapture(r));
}};
// add new expectations for code in the Runnable, with return values
new Expectations() {{
d.someMethod(); result = 42;
}};
// run the Runnable
r.get(0).run();
// verifications for the code in the Runnable
new Verifications() {{
d.otherMethod(42);
}};
}
}