You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Krzysztof Mackowiak (Jira)" <ji...@apache.org> on 2021/05/25 14:53:00 UTC
[jira] [Created] (CAMEL-16658) AmbiguousMethodCallException when
using Mockito mock as bean for camel-bean component.
Krzysztof Mackowiak created CAMEL-16658:
-------------------------------------------
Summary: AmbiguousMethodCallException when using Mockito mock as bean for camel-bean component.
Key: CAMEL-16658
URL: https://issues.apache.org/jira/browse/CAMEL-16658
Project: Camel
Issue Type: Bug
Components: camel-bean
Affects Versions: 3.x
Reporter: Krzysztof Mackowiak
Attachments: Tests_-_AmbiguousMethodCallException_when_using_Mockito_mock_as_bean_for_camel-bean_compon.patch
In Camel 2.x camel-bean component considered only public methods when trying to choose a method to call.
In Camel 3.x this behaviour was changed and now protected and package methods are also considered (it was implemented in the CAMEL-13298 task).
Unfortunately this change causes that using Mockito mocks as beans for camel-bean components (for example to test some Camel routes) causes an AmbiguousMethodCallException to be thrown.
Here is an example of such exception:
{code:java}
org.apache.camel.component.bean.AmbiguousMethodCallException: Ambiguous method invocations possible:
[public java.lang.String org.apache.camel.component.bean.MockitoMockForClassTest$MyService$MockitoMock$1368359973.doSomething(java.lang.String),
final java.lang.String org.apache.camel.component.bean.MockitoMockForClassTest$MyService$MockitoMock$1368359973.doSomething$accessor$MJMz0OHK(java.lang.String)]
on the exchange: Exchange[]
at org.apache.camel.component.bean.BeanInfo.chooseBestPossibleMethodInfo(BeanInfo.java:887)
...
{code}
This is caused by the fact that Mockito adds package level methods with the same argument list to created mock/spy.
Additional complication is added by the fact that Mockito 1.x (which uses CGLIB underneath) adds different methods than Mockito 2.x and 3.x (which uses Byte Buddy).
Here are 3 JUnit tests that reproduce this problem:
{code:java}
// NOTE: fails for Mockito 3.x and 2.x, but passes for Mockito 1.x
public class MockitoMockForClassTest extends ContextTestSupport {
@Test
public void testCallingMock() throws Exception {
Object response = template.requestBody("direct:start", "anything");
assertEquals("mocked answer", response);
}
@Override
protected Registry createRegistry() throws Exception {
MyService mockService = Mockito.mock(MyService.class);
when(mockService.doSomething(any())).thenReturn("mocked answer");
Registry answer = super.createRegistry();
answer.bind("myService", mockService);
return answer;
}
@Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
public void configure() throws Exception {
from("direct:start").bean("bean:myService");
}
};
}
public class MyService {
public String doSomething(String body) {
return "real answer";
}
}
}
{code}
{code:java}
// NOTE: fails for Mockito 3.x and 2.x, but passes for Mockito 1.x
public class MockitoSpyForClassTest extends ContextTestSupport {
@Test
public void testCallingSpy() throws Exception {
Object response = template.requestBody("direct:start", "anything");
assertEquals("mocked answer", response);
}
@Override
protected Registry createRegistry() throws Exception {
MyService mockService = Mockito.spy(new MyService());
when(mockService.doSomething(any())).thenReturn("mocked answer");
Registry answer = super.createRegistry();
answer.bind("myService", mockService);
return answer;
}
@Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
public void configure() throws Exception {
from("direct:start").bean("bean:myService");
}
};
}
public class MyService {
public String doSomething(String body) {
return "real answer";
}
}
}
{code}
{code:java}
// NOTE: fails for Mockito 1.x, but passes for Mockito 3.x and 2.x
public class MockitoMockForInterfaceTest extends ContextTestSupport {
@Test
public void testCallingMock() throws Exception {
Object response = template.requestBody("direct:start", "anything");
assertEquals("mocked answer", response);
}
@Override
protected Registry createRegistry() throws Exception {
MyService mockService = Mockito.mock(MyService.class);
when(mockService.doSomething(any())).thenReturn("mocked answer");
Registry answer = super.createRegistry();
answer.bind("myService", mockService);
return answer;
}
@Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
public void configure() throws Exception {
from("direct:start").bean("bean:myService");
}
};
}
public interface MyService {
String doSomething(String body);
}
}
{code}
--
This message was sent by Atlassian Jira
(v8.3.4#803005)