如何将 @Context 注释的字段注入 RestEasy @Provider?
How can I inject an @Context-annotated field into a RestEasy @Provider?
在 JBoss 容器中使用 RestEasy,我有一个用 @Provider
注释的 ExceptionMapper
,它可以通过 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());
}
}
但这会导致 MyExceptionMapper
中的 NullPointerException
我第一次引用其中一个 @Context
字段,这告诉我它们没有被注入。
我也试过:
- 使用
@Mocked
而不是 @Injectable
;
- 使用和不使用
@Tested
注释直接实例化 MyExceptionMapper
;
- 在我的测试中创建
Expectations
;和
- 以上的每个排列
在所有情况下,@Context
-注释字段都是 null
。
希望我只是遗漏了一些非常明显的东西?
由于没有更好的答案,我最终在测试中使用反射来为这两个属性注入值。不理想,但有效:
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
值的期望和验证。
我不是反射方面的专家,所以这可能不是 best/most 有效的方法,但它足以满足我的需求。
在 JBoss 容器中使用 RestEasy,我有一个用 @Provider
注释的 ExceptionMapper
,它可以通过 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());
}
}
但这会导致 MyExceptionMapper
中的 NullPointerException
我第一次引用其中一个 @Context
字段,这告诉我它们没有被注入。
我也试过:
- 使用
@Mocked
而不是@Injectable
; - 使用和不使用
@Tested
注释直接实例化MyExceptionMapper
; - 在我的测试中创建
Expectations
;和 - 以上的每个排列
在所有情况下,@Context
-注释字段都是 null
。
希望我只是遗漏了一些非常明显的东西?
由于没有更好的答案,我最终在测试中使用反射来为这两个属性注入值。不理想,但有效:
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
值的期望和验证。
我不是反射方面的专家,所以这可能不是 best/most 有效的方法,但它足以满足我的需求。