Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
public void execute() {
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(this::launch);
and I tried to mock Executors.newSingleThreadExecutor() to have an executorService that runs on the same thread as my tests, so that my assertions happens after the executions of the executorService and not before:
@RunWith(PowerMockRunner.class)
@PrepareForTest({
AnOtherClass.class,
Executors.class
public class TestClass {
@Before
public void setUp() throws Exception {
PowerMockito.mockStatic(Executors.class);
ExecutorService executorService = mock(ExecutorService.class);
implementAsDirectExecutor(executorService);
PowerMockito.when(Executors.newSingleThreadExecutor()).thenReturn(executorService);
private void implementAsDirectExecutor(ExecutorService executor) {
doAnswer(invocation -> {
Object[] args = invocation.getArguments();
Runnable runnable = (Runnable)args[0];
runnable.run();
return null;
}).when(executor).submit(any(Runnable.class));
@Test
public void testMethod() {
classToTest.execute();
.... //assert something
Problem :
Even with PowerMockito.when(Executors.newSingleThreadExecutor()).thenReturn(executorService);
the real method is called, and I don't get the mocked ExecutorService.
–
–
Solution 1
This issue could be resolved by adding the ClassToTest
to the @PrepareForTest
also.
@PrepareForTest({
AnOtherClass.class,
Executors.class,
ClassToTest.class
Solution 2
But I prefer the solution of @Andy, it's more clean:
I passed my ExecutorService in the constructor of ClassToTest
, and like that, I get rid of PowerMock:
public class ClassToTest{
public ClassToTest(ExecutorService executorService) {
public void execute() {
executorService.submit(this::launch);
A different way to think about this is to inject the ExecutorService
into the test-class for testing purposes:
public class ClassToTest {
private ExecutorService testExecutor;
public void execute() {
ExecutorService executor;
if (testExecutor == null) {
executor = Executors.newSingleThreadExecutor();
} else {
executor = testExecutor;
executor.submit(this::launch);
public void setTestExecutor(ExecutorService testExecutor) {
this.testExecutor = testExecutor;
Then you can use more standard interface mocking with PowerMockito as opposed to overriding the static classes.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.