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

时间:2019-04-10 11:29:25

标签: java jboss resteasy jmockit

在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

希望我只是想念一些很明显的东西?

1 个答案:

答案 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值的期望和验证。

我不是思考的专家,所以这可能不是最好/最有效的方法,但是足以满足我的需求。