#java #mocking #mockito #powermockito
Вопрос:
У меня есть класс Java, как показано ниже
public class MyClass {
private final ShowFactory showFactory;
private SomeShow someShow;
public MyClass(ShowFactory showFactory) {
this.showFactory = showFactory;
startShow();
}
public void startShow() {
someShow = showFactory.createShow();
someShow.start();
}
public void showSomething() {
MagicBox magicBox = new MagicBox();
someShow.showSomething(magicBox);
}
public void stopShow() {
someShow.stop();
}
}
и пытаюсь протестировать showSomething
метод. Полный тестовый файл выглядит следующим образом
public class MyClassTest {
private ShowFactory showFactory;
private SomeShow someShow;
@Before
public void setUp() {
showFactory = mock(ShowFactory.class);
someShow = mock(SomeShow.class);
when(showFactory.createShow()).thenReturn(someShow);
}
@Test
public void shouldStartShow() {
new MyClass(showFactory);
verify(someShow).start();
}
@Test
public void shouldShowSomething() throws Exception {
MagicBox magicBox = mock(MagicBox.class);
PowerMockito.whenNew(MagicBox.class).withAnyArguments().thenReturn(magicBox);
doNothing().when(someShow).showSomething(magicBox);
InOrder inOrder = inOrder(someShow);
MyClass myClass = new MyClass(showFactory);
myClass.showSomething();
inOrder.verify(someShow).start();
inOrder.verify(someShow).showSomething(magicBox);
}
@Test
public void shouldStopShow() {
MyClass myClass = new MyClass(showFactory);
myClass.stopShow();
verify(someShow).start();
verify(someShow).stop();
}
}
Но тест shouldShowSomething
проваливается с ошибкой Wanted but not invoked
. Чего — нибудь мне здесь не хватает? Есть какие-нибудь предложения?
Комментарии:
1. Я думаю, вам нужно еще несколько шагов, чтобы использовать
PowerMockito.whenNew
их для моделирования вызова конструктора github.com/powermock/powermock/wiki/… Поэтому его нужно запустить с помощью PowerMockRunner и использовать @PrepareForTest с нужным классом в нем. Издевательство над внутренними компонентами метода вплоть до вызова конструктора довольно глубоко. Не могли бы вы поочередно использовать сопоставители, чтобы утверждать, чтоmagicBox
он находится в желаемом состоянии? НравитсяinOrder.verify(someShow).showSomething(argThat(argument -> matchingLogicGoesHere));
.
Ответ №1:
Это было простое решение. После прочтения https://github.com/powermock/powermock/wiki/MockConstructor#quick-summary (спасибо @roby) оказывается, мне не хватало @PrepareForTest
аннотации для класса.
@RunWith(PowerMockRunner.class)
@PrepareForTest(MyClass.class)
public class MyClassTest {
...
}