【问题标题】:How to camel route test spring bean with mockito mocked bean如何用mockito模拟豆骆驼路线测试春豆
【发布时间】:2017-09-15 00:56:21
【问题描述】:

我希望能够测试从队列中消耗的路由,然后在涉及 spring 注入服务的 bean 中做一些工作,并使用 mockito 来有效地模拟这个服务。

我的春季路线如下:

    <camel:route id="msgemailqueue-to-emailservice">        
        <camel:from uri="activemq:emails" />
        <camel:bean ref="emailService" method="createEmailRequest"/>            
    </camel:route>

emailService bean 有一个自动连接的服务,然后在 createEmailRequest() 中调用该服务,该服务转到另一个服务并检索用户数据以供随后使用。

测试:

@RunWith(MockitoJUnitRunner.class)
public class TroubledEmailServiceImplTest extends CamelSpringTestSupport {

    @Produce(context = "messagingCamelContext")
    protected ProducerTemplate producer;

    @Mock
    private UserRestService userRestService;

    @Override
    protected AbstractApplicationContext createApplicationContext() {
        return new ClassPathXmlApplicationContext("messaging-camel-route-test-context.xml");
    }

    @Test
    public void testUserResponseToEmailQueue() throws Exception {
        context.addRoutes(new MyDynamcRouteBuilder(context, "direct:addEmailRequest", "activemq:emails"));

        Mockito.when(userRestService.getUserById(Mockito.anyLong())).thenReturn(
            new WebServiceResult<UserVO>(new UserVO()));

        CreateMessageRequest msgReq = new CreateMessageRequest();
        producer.sendBody("direct:addEmailRequest", msgReq);

        Mockito.verify(userRestService).getUserById(Mockito.anyLong());
        assertMockEndpointsSatisfied();
   }

bean如下:

@Override
public void createEmailRequest(final CreateMessageRequest request) throws CreateEmailException {

    LOGGER.trace("Entering createEmailRequest(request) " + Arrays.asList(new Object[] { request }));

    Validate.notNull(request, "CreateMessageRequest was null");

    WebServiceResult<UserVO> response;
    try {
        response = userRestService.getUserById(request.getId());
    } catch (final WebServiceException e) {
        throw new CreateEmailException("Error lookup up user data for email", e);
    }

    final UserVO userResponse = response.getData();

所有编译都正常,并且在运行路由时会触发,因为队列中会弹出一个对象,然后将其传递给 bean 并调用 createEmailRequest 并且对 mockito 模拟服务的调用正常

response = userRestService.getUserById(request.getId());

但即使响应为空

        Mockito.when(userRestService.getUserById(Mockito.anyLong())).thenReturn(
            new WebServiceResult<UserVO>(new UserVO()));

在测试中执行。似乎 bean 中的服务是一个不同的实例,即永远不会调用 mockito mock。

我做错了什么,也许我的测试方法也全错了,但这在理论上应该可行吗?我真的很希望能够在我的骆驼路线中模拟一个 bean 中的服务。

【问题讨论】:

    标签: spring unit-testing apache-camel mockito


    【解决方案1】:

    我正在使用 Camel Enhanced Spring Test 并通过了同样的问题。我只将@Mock 更改为@MockBean。我的 Camel 版本是 2.18。

    【讨论】:

      【解决方案2】:

      您在测试中创建的模拟 userRestService 必须与您在 bean 中使用的实例相同。我看不到您在哪里为 createEmailRequest 方法设置 userRestService。该服务需要与您在测试中创建的模拟对象相同。

      【讨论】:

      • 抱歉,它是在 bean 中自动装配的。 @Autowired 私有 UserRestService userRestService;在 Eclipse 中调试时,userRestService 是一个 Mockito 实例 - 调用 setUserRestService() 时 UserRestService$$EnhancerByMockitoWithCGLIB$$31de7f69 **id=72** 但内部时 UserRestService$$EnhancerByMockitoWithCGLIB$$31de7f69 id=132 createEmailRequest() 方法。我确定 Eclipse 中的 id 值并不重要,但有趣的是 toString 不同 - 当骆驼路线运行它时为“Mock for UserRestService,hashCode:4221046”,而当 spring 调用 setter 时为“UserRestService”。
      【解决方案3】:

      我已经解决了这个问题 - 过失。我的测试类有效地创建了服务的两个实例 - 一个通过 spring 应用程序上下文,另一个由于 @RunWith(MockitoJUnitRunner.class) 加上 @mock 注释。现在通过一次模拟创建来解决。总而言之,这只是我的弹簧接线问题。非常感谢@mike-pone。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-21
        • 1970-01-01
        相关资源
        最近更新 更多