如何将 @Context 注释的字段注入 RestEasy @Provider?

How can I inject an @Context-annotated field into a RestEasy @Provider?

在 JBoss 容器中使用 RestEasy,我有一个用 @Provider 注释的 ExceptionMapper,它可以通过 HttpServletRequestHttpServletResponse 访问 @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 字段,这告诉我它们没有被注入。

我也试过:

在所有情况下,@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 有效的方法,但它足以满足我的需求。