如何将 @Context 注释字段注入 RestEasy @Provider?
Posted
技术标签:
【中文标题】如何将 @Context 注释字段注入 RestEasy @Provider?【英文标题】:How can I inject an @Context-annotated field into a RestEasy @Provider? 【发布时间】:2019-08-31 20:21:09 【问题描述】:在 JBoss 容器中使用 RestEasy,我有一个带有 @Provider
注释的 ExceptionMapper
,它可以通过 @Context
注释访问 HttpServletRequest
和 HttpServletResponse
,如下所示:
@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());
但这会在我第一次引用@Context
字段之一时导致MyExceptionMapper
中的NullPointerException
,这告诉我它们没有被注入。
我也试过了:
使用@Mocked
代替@Injectable
;
直接实例化MyExceptionMapper
有和没有@Tested
注释;
在我的测试中创建Expectations
;和
上述的每一个排列
在所有情况下,@Context
-annotated 字段都是null
。
希望我只是遗漏了一些非常明显的东西吗?
【问题讨论】:
你使用-javaagent
参数初始化JMockit了吗?
@Rogério - 不知情。我只是在 IntelliJ 中将测试作为普通 JUnit 测试运行,并且在 Maven POM 中看不到对 -javaagent
的任何引用。我应该使用它吗?
如果您使用的是最新版本的 JMockit,那么可以。
【参考方案1】:
在没有更好的答案的情况下,我最终在测试中使用反射来为这两个属性注入值。不理想,但它有效:
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
值的期望和验证。
我不是反思方面的专家,所以这可能不是最好/最有效的方法,但它足以满足我的需求。
【讨论】:
以上是关于如何将 @Context 注释字段注入 RestEasy @Provider?的主要内容,如果未能解决你的问题,请参考以下文章
从弹簧配置中初始化或将字符串注入静态字段 beforeClass (JUNIT) 的优雅方法?