开发者

How to obtain a reference to a Runnable instance passed to a Thread constructor using PowerMock(ito)?

开发者 https://www.devze.com 2023-04-13 05:28 出处:网络
There\'s a black box class which creates a Thread using its constructor accepting an instance of Runnable as the argument:

There's a black box class which creates a Thread using its constructor accepting an instance of Runnable as the argument:

public class Service {

  public static Task implements Runnable {

    @Override
    public void run() {

      doSomeHeavyProcessing();
    }
  }

  public void doAsynchronously() {

    new Thread(new Task()).start();
  }
}

I want to intercept the constructor call and get a reference to the passing Task implementing Runnable. This is the code so far:

@RunWith(PowerMockRunner.class)
@PrepareForTest(Service.class)
public class ServiceTest {

  @Test
  public void testService() {

    ArgumentCaptor<Runnable> runnables = ArgumentCaptor.forClass(Runnable.class);
    Thread thread = Mockito.mock(Trhead.class);
    whenNew(Thread.class.getContructor(Runnable.class)).
      withArguments(runnables.capture)).thenReturn(thread);

    new Service().doAsynchronously();

    System.out.println("all runnables: " + runnables.getAllValues());

    for (Runnable r : runnables.getAllValues()) r.run();

    // perform some assertions after the code meant to be executed in a new
    // thread has开发者_开发百科 been executed in the current (main) thread
  }
}

Test execution will print out:

all runnables: []

Is there a way of grabbing a reference to all Runnable objects or Thread objects returned by the constructor? I want to execute the asynchronous code either in the current (main) thread or join created threads and perform assertions.


First your code had some typo errors, and once corrected it didn't work when tried in the IDE. The code throws a VerifyError about the Task initialization. Making Task public helped.

Once every was alright, your code worked as expected, meaning your runnables were captured.

Although I would go for this stubbing syntax instead :

whenNew(Thread.class).withParameterTypes(Runnable.class)
    .withArguments(runnables.capture()).thenReturn(mock);

You should investigate your real code to see if it got correctly stubbed.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号