0

我们的测试存在问题,即当资源包装在 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));
    }
}
4

1 回答 1

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;
    }
}
于 2013-08-15T09:12:42.657 回答