在JBoss容器中使用RestEasy时,我有一个ExceptionMapper
注释的@Provider
,它可以通过HttpServletRequest
注释访问HttpServletResponse
和@Context
,像这样:
@Provider
public class MyExceptionMapper implements ExceptionMapper<Throwable> {
@Context
private HttpServletRequest httpServletRequest;
@Context
private HttpServletResponse httpServletResponse;
@Override
public Response toResponse(final Throwable exception) {
...
return response;
}
}
我是RestEasy的新手,来自Spring背景,因此天真地假设我能够注入这两个字段并在单元测试中模拟它们,但这似乎比我想象的要难!
如果模拟框架是相关的,那么我正在使用JMockit,它也是新手。到目前为止,我已经能够将我对Mockito的知识应用到其中,并且取得了很大的成功。
除了在单元测试中运行嵌入式容器的大量建议之外,我没有在主题周围进行搜索找到很多东西。我并不完全反对这一点,但是当我试图编写一个简单的单元测试时,感觉就像是过分杀伤。
我已经在测试中尝试了几件事,最近一次是这样:
public class MyExceptionMapperTest {
@Injectable
private HttpServletRequest httpServletRequest;
@Injectable
private HttpServletResponse httpServletResponse;
@Tested
private MyExceptionMapper exceptionMapper;
@Test
public void test() {
exceptionMapper.toResponse(new Throwable());
}
}
但这会在我第一次引用NullPointerException
字段之一时在MyExceptionMapper
中产生@Context
,这告诉我它们没有被注入。
我也尝试过:
@Mocked
代替@Injectable
; MyExceptionMapper
注释直接实例化@Tested
; Expectations
;和在所有情况下,带有@Context
注释的字段均为null
。
希望我只是想念一些很明显的东西?
答案 0 :(得分:0)
在没有更好答案的情况下,我最终在测试中使用反射来注入这两个属性的值。不理想,但是可以工作:
public class MyExceptionMapperTest {
@Mocked
private HttpServletRequest mockHttpServletRequest;
@Mocked
private HttpServletResponse mockHttpServletResponse;
private MyExceptionMapper exceptionMapper = new MyExceptionMapper();
@Before
public void setup() {
Field httpServletRequest = exceptionMapper.getClass().getDeclaredField("httpServletRequest");
httpServletRequest.setAccessible(true);
httpServletRequest.set(exceptionMapper, mockHttpServletRequest);
Field httpServletResponse = exceptionMapper.getClass().getDeclaredField("httpServletResponse");
httpServletResponse.setAccessible(true);
httpServletResponse.set(exceptionMapper, mockHttpServletResponse);
}
}
然后,在测试中,我可以像平常一样设置对两个@Mocked
值的期望和验证。
我不是思考的专家,所以这可能不是最好/最有效的方法,但是足以满足我的需求。