无法在 JerseyTest 中注入 Providers mock
can't inject Providers mock in JerseyTest
我正在从过滤器中的上下文中获取 Providers
以进行定义 ObjectMapper
public class Filter implements ContainerRequestFilter, ContainerResponseFilter {
@Context
private Providers providers;
@Context
private HttpServletRequest request;
private ObjectMapper getObjectMapper() {
ContextResolver<ObjectMapper> contextResolver = providers.getContextResolver(ObjectMapper.class, MediaType.APPLICATION_JSON_TYPE);
if (contextResolver == null) {
return new ObjectMapper();
}
return contextResolver.getContext(null);
}
}
但在测试中我无法使用带有 HttpServletRequest
的抽象活页夹在此过滤器中注入模拟,它工作正常但 Providers
不是模拟。测试示例:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "..." })
@PrepareForTest({ ... })
public class Test extends JerseyTest {
@Rule
public PowerMockRule rule = new PowerMockRule();
private HttpServletRequest request;
private Providers providers;
@Override
protected Application configure() {
ResourceConfig config = new ResourceConfig(TestResource.class, Filter.class);
providers = mock(Providers.class);
request = mock(HttpServletRequest.class);
config.register(new AbstractBinder() {
@Override
protected void configure() {
bind(providers).to(Providers.class);
}
});
config.register(new AbstractBinder() {
@Override
protected void configure() {
bind(request).to(HttpServletRequest.class);
}
});
return config;
}
为什么 HttpServletRequest
在过滤器中是 mock 而 Providers
不是?
提供者不应该被嘲笑。它由框架处理。您想要添加的任何提供商,只需在 ResourceConfig
上注册即可。我不知道您在此尝试中做错了什么,但下面是一个完整的工作示例,其中发现 ContextResolver
就好了。
如果您仍然无法理解,请像我一样提供一个完整的工作 class 示例(没有任何模拟或 Spring 东西)。
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.Providers;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Assert;
import org.junit.Test;
public class ContextResolverTest extends JerseyTest {
@Provider
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public static class OMContextResolver implements ContextResolver<ObjectMapper> {
private final ObjectMapper mapper = new ObjectMapper();
@Override
public ObjectMapper getContext(Class<?> type) {
return mapper;
}
}
@Provider
public static class Filter implements ContainerRequestFilter {
@Context
private Providers providers;
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
ContextResolver<ObjectMapper> contextResolver
= providers.getContextResolver(ObjectMapper.class,
MediaType.APPLICATION_JSON_TYPE);
if (contextResolver == null) {
requestContext.abortWith(
Response.serverError().entity("no resolver").build());
} else {
ObjectMapper mapper = contextResolver.getContext(null);
if (mapper == null) {
requestContext.abortWith(
Response.serverError().entity("no mapper").build());
return;
}
requestContext.abortWith(
Response.ok("resolver found").build());
}
}
}
@Path("test")
public static class TestResource {
@GET
public String dummyGet() {
return "Boo";
}
}
@Override
public Application configure() {
ResourceConfig config = new ResourceConfig();
config.register(TestResource.class);
config.register(OMContextResolver.class);
config.register(Filter.class);
return config;
}
@Test
public void contextResolverIsOk() {
Response response = target("test").request().get();
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("resolver found", response.readEntity(String.class));
response.close();
}
}
我正在从过滤器中的上下文中获取 Providers
以进行定义 ObjectMapper
public class Filter implements ContainerRequestFilter, ContainerResponseFilter {
@Context
private Providers providers;
@Context
private HttpServletRequest request;
private ObjectMapper getObjectMapper() {
ContextResolver<ObjectMapper> contextResolver = providers.getContextResolver(ObjectMapper.class, MediaType.APPLICATION_JSON_TYPE);
if (contextResolver == null) {
return new ObjectMapper();
}
return contextResolver.getContext(null);
}
}
但在测试中我无法使用带有 HttpServletRequest
的抽象活页夹在此过滤器中注入模拟,它工作正常但 Providers
不是模拟。测试示例:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "..." })
@PrepareForTest({ ... })
public class Test extends JerseyTest {
@Rule
public PowerMockRule rule = new PowerMockRule();
private HttpServletRequest request;
private Providers providers;
@Override
protected Application configure() {
ResourceConfig config = new ResourceConfig(TestResource.class, Filter.class);
providers = mock(Providers.class);
request = mock(HttpServletRequest.class);
config.register(new AbstractBinder() {
@Override
protected void configure() {
bind(providers).to(Providers.class);
}
});
config.register(new AbstractBinder() {
@Override
protected void configure() {
bind(request).to(HttpServletRequest.class);
}
});
return config;
}
为什么 HttpServletRequest
在过滤器中是 mock 而 Providers
不是?
提供者不应该被嘲笑。它由框架处理。您想要添加的任何提供商,只需在 ResourceConfig
上注册即可。我不知道您在此尝试中做错了什么,但下面是一个完整的工作示例,其中发现 ContextResolver
就好了。
如果您仍然无法理解,请像我一样提供一个完整的工作 class 示例(没有任何模拟或 Spring 东西)。
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.Providers;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Assert;
import org.junit.Test;
public class ContextResolverTest extends JerseyTest {
@Provider
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public static class OMContextResolver implements ContextResolver<ObjectMapper> {
private final ObjectMapper mapper = new ObjectMapper();
@Override
public ObjectMapper getContext(Class<?> type) {
return mapper;
}
}
@Provider
public static class Filter implements ContainerRequestFilter {
@Context
private Providers providers;
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
ContextResolver<ObjectMapper> contextResolver
= providers.getContextResolver(ObjectMapper.class,
MediaType.APPLICATION_JSON_TYPE);
if (contextResolver == null) {
requestContext.abortWith(
Response.serverError().entity("no resolver").build());
} else {
ObjectMapper mapper = contextResolver.getContext(null);
if (mapper == null) {
requestContext.abortWith(
Response.serverError().entity("no mapper").build());
return;
}
requestContext.abortWith(
Response.ok("resolver found").build());
}
}
}
@Path("test")
public static class TestResource {
@GET
public String dummyGet() {
return "Boo";
}
}
@Override
public Application configure() {
ResourceConfig config = new ResourceConfig();
config.register(TestResource.class);
config.register(OMContextResolver.class);
config.register(Filter.class);
return config;
}
@Test
public void contextResolverIsOk() {
Response response = target("test").request().get();
Assert.assertEquals(200, response.getStatus());
Assert.assertEquals("resolver found", response.readEntity(String.class));
response.close();
}
}