@Resteasy 单元测试中未注入上下文

问题描述 投票:0回答:1

我使用模拟和 MockDispatcherFactory 进行单元测试来测试我的 Rest 应用程序。这些适用于以前版本的 Resteasy,但当更新到 3.15.0.Final (Wildfly 24) 时,不再注入 @Context 对象。这是我的测试代码:

private MockHttpResponse request(final Method method, final String uri, final HttpServletRequest mockedRequest,
                                     final Object service, final Optional<byte[]> content,
                                     final Optional<String> contentType,
                                     final Optional<Map<Class<?>, Object>> contextObjects,
                                     final Optional<Map<String, String>> cookies)
                    throws URISyntaxException, IOException, ClassNotFoundException, InvocationTargetException,
                    NoSuchMethodException, InstantiationException, IllegalAccessException {

        final Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
        dispatcher.getRegistry().addSingletonResource(service);
        dispatcher.getDefaultContextObjects().put(HttpServletRequest.class, mockedRequest);
        dispatcher.getProviderFactory().registerProviderInstance(new JacksonTestConfigurator());
        if (contextObjects.isPresent()) {
            for (Map.Entry<Class<?>, Object> contextObject : contextObjects.get().entrySet()) {
                dispatcher.getDefaultContextObjects().put(contextObject.getKey(), contextObject.getValue());
                pushContext(contextObject.getKey(), contextObject.getValue());
            }
        }

        addMappings(dispatcher);

        final MockHttpRequest request = performRequest(method, uri);
        request.accept(MediaType.APPLICATION_JSON);
        request.contentType(contentType.isPresent() ? contentType.get() : MediaType.APPLICATION_JSON_TYPE.toString());

        if (cookies.isPresent()) {
            for (Map.Entry<String, String> cookieEntry : cookies.get().entrySet()) {
                request.cookie(cookieEntry.getKey(), cookieEntry.getValue());
            }
        }

        if (content.isPresent()) {
            request.content(content.get());
        }
        final MockHttpResponse response = new MockHttpResponse();

        dispatcher.invoke(request, response);

        return response;
    }

    @SuppressWarnings("unchecked")
    public <T> void pushContext(Class<?> clasz, Object obj) {
        Class<T> type = (Class<T>) clasz;
        ResteasyProviderFactory.pushContext(type, (T) obj);
    }

我尝试了两种方法,正如你在代码中看到的:

  • dispatcher.getDefaultContextObjects().put(contextObject.getKey(), contextObject.getValue());
  • ResteasyProviderFactory.pushContext(type, (T) obj); 我的休息终点:
 public void updatePassword(@PathParam(value = "panelist") String panelistId,
             @Context Optional<AuthenticatedUser> authenticatedPanelist,
             CurrentAndNewCredentialsDto dto)
             throws ForbiddenException, InvalidArgumentException, UnexpectedException {

          assertAuthenticatedUserHasAccessToPanelistResource(authenticatedUser, panelistId);

          CurrentAndNewPassword currentAndNewPassword =
                  CurrentAndNewCredentialsDtoMapper.INSTANCE.toPasswordModel(dto);

          Try<Void> result = facade.updatePassword(panelistId, currentAndNewPassword);
          if (result.isFailure()) {
                Throwable failure = result.getFailure();
                if (failure instanceof InvalidArgumentException) {
                     logger.warn("Failure when panelist tries to updatePassword, for panelist {}", panelistId, failure);
                     throw (InvalidArgumentException) failure;
                } else {
                     throw new UnexpectedException(failure);
                }
          }
     }

有什么建议吗?

我尝试了两种方法,正如你在代码中看到的:

  • dispatcher.getDefaultContextObjects().put(contextObject.getKey(), contextObject.getValue());
  • ResteasyProviderFactory.pushContext(type, (T) obj);

我希望 @Context 注入可以像旧版本一样工作

java unit-testing jax-rs resteasy
1个回答
0
投票

我找到问题所在了。 我向上下文推送了一个可选的,而不是直接推送所需的对象,因为在休息端点我想要一个可选的。事实证明,如果您推送对象并期望可选的 Resteasy 为您包装它,那么而不是:

ResteasyProviderFactory.pushContext(Optional.class,  Optional.ofNullable(authenticatedUser));

必须是:

ResteasyProviderFactory.pushContext(AuthenticatedUser.class, authenticatedUser);

然后在端点中,您可以作为可选注入:

@Context Optional<AuthenticatedUser> authenticatedUser
© www.soinside.com 2019 - 2024. All rights reserved.