我们的测试存在一个问题,即当资源包装在TransactionalProxy中时,字段UriInfo未正确注入。 我们尝试使用SpringResourceFactory,但这也无济于事。
我尝试提取此用例的相关类:
public class InMemoryClientFactory implements FactoryBean<InMemoryClientExecutor>{
@Inject
private SessionResource sessionResource;
@Override
public InMemoryClientExecutor getObject() throws Exception {
Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
Registry registry = dispatcher.getRegistry();
registry.addSingletonResource(sessionResource);
final InMemoryClientExecutor inMemoryClientExecutor = new InMemoryClientExecutor(dispatcher);
}
@Override
public Class getObjectType() {
return InMemoryClientExecutor.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
@Path("session")
public interface SessionResource {
@GET
@Path("{sessionId}")
@Produces({MediaType.APPLICATION_XML})
Response get(@PathParam("sessionId") String sessionId);
@DELETE
@Path("{sessionId}")
Response delete(@PathParam("sessionId") String sessionId);
}
@Service
@Transactional
public class SessionResourceImpl implements SessionResource {
@Context
private UriInfo uriInfo;
@Override
public Response get(String sessionId) {
// uriInfo will be null here
String url = uriInfo.getBaseUriBuilder().path(SessionResource.class).path(SessionResource.class, "delete").build(sessionId)
.toString());
return Response.ok(session).build();
@Override
public Response delete(String sessionId) {
System.out.println("Deleted Session "+1);
}
}
@ContextConfiguration(locations = ["classpath:/META-INF/testContext.xml"])
@Transactional
@RunWith(SpringJUnit4ClassRunner.class)
public class SessionResourceIT {
@Inject
InMemoryRestClientFactory inMemoryClientFactory;
@Inject
SessionResource resource;
@Test
public void test() {
SessionResource resource = inMemoryClientFactory.createProxy(SessionResource.class);
ClientResponse cr = client.get(sessionId);
assertNotNull(cr.getEntity(String.class));
}
}
答案 0 :(得分:0)
可能的解决方法是打开测试的事务代理,只要测试本身使用@Transactional注释,这就可以工作。我希望有人有比这更好的解决方案。
public class InMemoryClientFactory implements FactoryBean<InMemoryClientExecutor>{
@Inject
private SessionResource sessionResource;
@Override
public InMemoryClientExecutor getObject() throws Exception {
Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
Registry registry = dispatcher.getRegistry();
registry.addSingletonResource(unwrapProxy(sessionResource));
final InMemoryClientExecutor inMemoryClientExecutor = new InMemoryClientExecutor(dispatcher);
}
@Override
public Class getObjectType() {
return InMemoryClientExecutor.class;
}
@Override
public boolean isSingleton() {
return true;
}
private static Object unwrapProxy(Object bean) throws Exception {
Object result = bean;
/*
* If the given object is a proxy, set the return value as the object
* being proxied, otherwise return the given object.
*/
if (AopUtils.isAopProxy(bean) && bean instanceof Advised) {
Advised advised = (Advised) bean;
result = advised.getTargetSource().getTarget();
}
return result;
}
}