- A Concurrent Affair - https://www.concurrentaffair.org -

Capturing a Runnable with JMockit and Executing It

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:

  1. Check that we call ExecutorService.submit
  2. Run the Runnable that was passed to submit
  3. Mock someMethod and return some value, and
  4. 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 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);
}};
}
}

[1] [2]Share [3]