2

我正在尝试对基于 Spring MVC 的控制器进行单元测试。此控制器调用服务。该服务实际上是远程的,并且通过 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 不是模拟的,它毕竟是 JsonRpcProxy。我已经以这种方式成功地测试了一个不同的控制器,但是那个控制器并没有使用代理到它的服务。

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

谢谢你的帮助!

4

3 回答 3

1

Note that I'm not instantiating the UserController myself, anywhere; spring/spring-mvc does that.

This means that you're not writing a unit test. This is testing the spring wiring which makes it an integration test. When writing a unit test you instantiate the class under test and supply the dependencies yourself. This allows you to isolate the logic in the class being tested by providing mocked instances of the classes dependencies. That's where jmockit comes in.

于 2013-01-20T21:24:46.997 回答
1

如果您正在对 UserController 进行单元测试,为什么不自己实例化它。将 Spring 排除在外,然后自行测试。

您在这里测试的不是 UserController,而是测试它的 Spring 接线和它的请求映射。

于 2013-01-20T20:43:46.893 回答
0

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

@Mocked IdMService service;

@Before
public void setUp() {
 controller.setIdMService(service);
   ...
}
于 2013-02-08T20:07:29.750 回答