Как получить ссылку на экземпляр Runnable, переданный конструктору Thread с помощью PowerMock (ito)? - PullRequest
0 голосов
/ 13 октября 2011

Существует класс черного ящика, который создает Thread, используя его конструктор, принимающий экземпляр Runnable в качестве аргумента:

public class Service {

  public static Task implements Runnable {

    @Override
    public void run() {

      doSomeHeavyProcessing();
    }
  }

  public void doAsynchronously() {

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

Я хочу перехватить вызов конструктора и получить ссылку на передаваемую Task реализацию Runnable. Это код до сих пор:

@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
  }
}

Выполнение теста выведет на печать:

all runnables: []

Есть ли способ получить ссылку на все Runnable объекты или Thread объекты, возвращаемые конструктором? Я хочу выполнить асинхронный код либо в текущем (основном) потоке, либо присоединиться к созданным потокам и выполнить утверждения.

1 Ответ

1 голос
/ 13 октября 2011

Сначала в вашем коде было несколько опечаток, и однажды исправленный он не работал при попытке в IDE. Код выдает VerifyError об инициализации Task. Помогло Task public.

Когда все было в порядке, ваш код работал должным образом, а это значит, что ваши исполняемые файлы были захвачены.

Хотя я бы вместо этого использовал этот синтаксис заглушки:

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

Вы должны исследовать свой реальный код, чтобы узнать, правильно ли он заглушен.

...