2016-07-21 4 views
0

У меня есть WicketPage с закачиваемой поле с КДИ следующим образом:Mocking впрыскивается поля с @ javax.inject.Inject с Mockito и калитка вызывает Калитка для лечения в поле ребенка компонента

public class Page extends BaseWebPage { 
private static final long serialVersionUID = 1L; 

@Inject 
private Facade facade; 

public Page() { 
    super("Title"); 
} 
} 

У меня есть UnitTest в котором я высмеиваю указанное поле:

@RunWith(MockitoJUnitRunner.class) 
public class PageTest{ 

    @Mock 
    private Facade facadeMock; 

    @InjectMocks 
    private Page cut; 

    WicketTester tester = new WicketTester(new MockApplication()); 

    @Before 
    public void setUp() { 
     Entity entity = newEntity("1", "John")); 
     Mockito.when(facadeMock.find()).thenReturn(entity); 
    } 

    @Test 
    public void testOverzicht() { 
     tester.startPage(cut); 
//below line throws stackTrace 
     tester.assertRenderedPage(Page.class); 
    } 
} 

Странно, Калитка не может понять смысл моего впрыскиваемого макета. В какой-то момент Wicket начинает обрабатывать компоненты, из которых FacadeMock внезапно становится одним. Затем он не выполняет экземпляр проверки компонентов, который не работает, потому что он- это прокси-сервер Mockito'd, который заставляет Wicket выкидывать исключение IllegalArgumentException. Затем он продолжает разбираться, а затем отбрасывать facadeMock в Object [] в его метод отсоединения. Stacktrace добавлено ниже для пояснения, которое вызывает исключение classCastException.

ПРИМЕЧАНИЕ. Имена классов и пакетов изменены в целях конфиденциальности.

java.lang.IllegalArgumentException: Unknown type of object facadeMock 
    at org.apache.wicket.MarkupContainer.getId(MarkupContainer.java:1068) 
    at org.apache.wicket.MarkupContainer.children_indexOf(MarkupContainer.java:1130) 
    at org.apache.wicket.MarkupContainer.put(MarkupContainer.java:1318) 
    at org.apache.wicket.MarkupContainer.add(MarkupContainer.java:175) 
    at nl.app.Page.onInitialize(Page.java:53) 
    at org.apache.wicket.Component.fireInitialize(Component.java:877) 
    at org.apache.wicket.MarkupContainer.internalInitialize(MarkupContainer.java:961) 
    at org.apache.wicket.Page.isPageStateless(Page.java:463) 
    at org.apache.wicket.request.handler.render.WebPageRenderer.respond(WebPageRenderer.java:244) 
    at org.apache.wicket.util.tester.BaseWicketTester$LastPageRecordingPageRendererProvider$1.respond(BaseWicketTester.java:2755) 
    at org.apache.wicket.core.request.handler.RenderPageRequestHandler.respond(RenderPageRequestHandler.java:175) 
    at org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor.respond(RequestCycle.java:890) 
    at org.apache.wicket.request.RequestHandlerStack.execute(RequestHandlerStack.java:64) 
    at org.apache.wicket.request.cycle.RequestCycle.execute(RequestCycle.java:261) 
    at org.apache.wicket.request.cycle.RequestCycle.processRequest(RequestCycle.java:218) 
    at org.apache.wicket.request.cycle.RequestCycle.processRequestAndDetach(RequestCycle.java:289) 
    at org.apache.wicket.util.tester.BaseWicketTester.processRequest(BaseWicketTester.java:712) 
    at org.apache.wicket.util.tester.BaseWicketTester.processRequest(BaseWicketTester.java:651) 
    at org.apache.wicket.util.tester.BaseWicketTester.startPage(BaseWicketTester.java:876) 
    at org.apache.wicket.util.tester.BaseWicketTester.startPage(BaseWicketTester.java:893) 
    at nl.app.Page.testOverzicht(PageTest.java:67) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37) 
    at java.lang.reflect.Method.invoke(Method.java:611) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) 
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
    at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37) 
    at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 
ERROR [RequestHandlerStack.detach()] Error detaching RequestHandler 
java.lang.ClassCastException: nl.app.common.facade.Facade$$EnhancerByMockitoWithCGLIB$$7b6f60ae incompatible w 
ith [Ljava.lang.Object; 
    at java.lang.ClassCastException.<init>(ClassCastException.java:58) 
    at org.apache.wicket.MarkupContainer.children_size(MarkupContainer.java:1305) 
    at org.apache.wicket.MarkupContainer.detachChildren(MarkupContainer.java:1603) 
    at org.apache.wicket.Component.detach(Component.java:1186) 
    at org.apache.wicket.core.request.handler.PageProvider.detach(PageProvider.java:327) 
    at org.apache.wicket.core.request.handler.RenderPageRequestHandler.detach(RenderPageRequestHandler.java:156) 
    at org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor.detach(RequestCycle.java:901) 
    at org.apache.wicket.request.RequestHandlerStack.detach(RequestHandlerStack.java:180) 
    at org.apache.wicket.request.cycle.RequestCycle.onDetach(RequestCycle.java:636) 
    at org.apache.wicket.request.cycle.RequestCycle.detach(RequestCycle.java:589) 
    at org.apache.wicket.request.cycle.RequestCycle.processRequestAndDetach(RequestCycle.java:293) 
    at org.apache.wicket.util.tester.BaseWicketTester.processRequest(BaseWicketTester.java:712) 
    at org.apache.wicket.util.tester.BaseWicketTester.processRequest(BaseWicketTester.java:651) 
    at org.apache.wicket.util.tester.BaseWicketTester.startPage(BaseWicketTester.java:876) 
    at org.apache.wicket.util.tester.BaseWicketTester.startPage(BaseWicketTester.java:893) 
    at nl.app.Page.testOverzicht(PageTest.java:67) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37) 
    at java.lang.reflect.Method.invoke(Method.java:611) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) 
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
    at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37) 
    at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 
+0

Интересно, как facadeMock пробирается детей странице. Не могли бы вы разместить точки останова в MarkupContainer $ ChildList, чтобы узнать, когда он будет добавлен? – svenmeier

+0

Это не экземпляр ChildList, дочернее поле - это facadeMock. Я добавил точку останова почти везде, но я понятия не имею, откуда она взялась. – rbottel

+0

Пожалуйста, создайте быстрый запуск, чтобы мы могли отладить проблему. – svenmeier

ответ

0

Я собираюсь предложить несколько иной подход, который не будет использовать @InjectMocks.

С КДИ точки зрения, способ достижения поведения, где один компонент использует другую реализацию в тестах (издевались) и в реальном сценарии (в полном объеме) является использование @Alternative. Это позволяет делать то же самое, что и насмешка, но ... ну, без насмешек. Сам CDI spec говорит об альтернативах в контексте насмешек.

Способ, которым он работает, заключается в следующем. Во-первых у вас есть фасоль с его реальной реализации:

public MyBean { 
    public void awesomeMethod() { 
    doStuff(); //do what you really want and or need here 
    } 
} 

Теперь есть этот другой @Alternative боб, который расширяет боб:

@Alternative 
public MyMockedBean extends MyBean { 
    public void awesomeMethod() { 
    // do some other, (mocked) stuff here, or don't do anything at all 
    } 
} 

Теперь, наконец, но не в последнюю очередь, @Alternative по умолчанию отключена , Это означает, что CDI обычно игнорирует его и вместо этого использует исходный компонент. Чтобы включить его, вы можете использовать два подхода:

  • @Priority, что позволяет использовать его все время и по всему миру. Вы не хотите этого в своем случае.
  • beans.xml, или более, перечислив альтернативу в beans.xml. Таким образом вы включаете альтернативу в базу данных по бонусу. Это путь: - просто добавьте другой тестер beans.xml в свои тесты и перечислите @Alternative. Таким образом, вы оставите стандартное поведение из области тестирования и будете использовать «издевку» в ваших тестах.

beans.xml должен содержать следующие строки для того, чтобы позволить @Alternative:

<alternatives> 
    <class>com.whatever.MyMockedBean</class> 
</alternatives>