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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | public class DemoWithRunnableTest { @Mocked DemoWithRunnable.Dependency d; @Mocked ExecutorService e; @Test public void testDoSomething() { DemoWithRunnable impl = new DemoWithRunnable(d, e); impl.doSomething(); List<Runnable> r = new ArrayList<>(); // 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); }}; } } |