如何模拟弹簧注入的服务代理?

时间:2013-01-20 20:34:00

标签: spring spring-mvc jmockit

我正在尝试对基于Spring MVC的Controller进行单元测试。 该控制器调用服务。该服务实际上是远程的,并通过JSON-RPC向控制器公开,特别是com.googlecode.jsonrpc4j.s​​pring.JsonProxyFactoryBean

控制人员:

@Controller
@RequestMapping("/users")
public class UserController {

    /**
     * ID manager service that will be used.
     */
    @Autowired
    IdMService idMService;
    ...
    @ResponseBody
    @RequestMapping(value = "/{userId}", method = GET)
    public UserAccountDTO getUser(@PathVariable Long userId, HttpServletResponse response) throws Exception {
        try {
            return idMService.getUser(userId);
        } catch (JsonRpcClientException se) {
            sendJsonEncodedErrorRepsonse(response, se);
            return null;
        }
    }
    ...
}

spring配置提供了如下的IdMService:

<!-- Create the proxy for the Access Control service -->
<bean class="com.googlecode.jsonrpc4j.spring.JsonProxyFactoryBean">
    <property name="serviceUrl" value="${access_control.service.url}" />
    <property name="serviceInterface" value="com.phtcorp.service.accesscontrol.IdMService" />
</bean>

因此,注入控制器的IdMService实际上是一个JSON-RPC代理,实现了IdMService接口。

我想测试控制器,但是模拟了IdMService。我有这个:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/test-context.xml" })
@SuppressWarnings("javadoc")
public class TestUserController {
    @Autowired
    private ApplicationContext applicationContext;

    private HandlerAdapter handlerAdapter;

    private MockHttpServletRequest request;
    private MockHttpServletResponse response;

    @Mocked IdMService service;

    @Test
    public void getUser() throws Exception {
        request.setMethod(RequestMethod.GET.name());
        request.setRequestURI("/users/1");
        HandlerMethod handler = (HandlerMethod) getHandler(request);
        handlerAdapter.handle(request, response, handler);
        new Verifications() {{
            service.getUser(1L); times=1;
        }};
    }
...
}

但是,我发现注入控制器的IdMService不是mock,毕竟它是JsonRpcProxy。我已经以这种方式成功测试了一个不同的控制器,但是那个没有使用代理服务器。

所以问题是:如何使用jmockit将模拟IdMService注入UserController?请注意,我没有在任何地方自己实例化UserController; spring / spring-mvc就是这么做的。

感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

如果您正在对UserController进行单元测试,为什么不自己实例化它。让Spring脱离图片,只需自己测试一下。

你没有在这里测试UserController,只是测试它的Spring连接和它的请求映射。

答案 1 :(得分:1)

  

请注意,我没有在任何地方自己实例化UserController; spring / spring-mvc就是这么做的。

这意味着您没有编写单元测试。这是测试弹簧接线,使其成为集成测试。在编写单元测试时,您将实例化测试中的类并自己提供依赖项。这允许您通过提供类依赖项的模拟实例来隔离正在测试的类中的逻辑。这就是jmockit的用武之地。

答案 2 :(得分:0)

我通过自己注入模拟解决了我的问题:

@Mocked IdMService service;

@Before
public void setUp() {
 controller.setIdMService(service);
   ...
}