[英]Retrieve a managed bean from a JerseyTest container with jersey-spring3
[英]How to access Spring Bean from JerseyTest subclass
这是我的抽象类,它从给定的Spring上下文开始Jersey:
public abstract class AbstractJerseyTest extends JerseyTest {
public void setUp() throws Exception {
super.setUp();
}
@AfterClass
public void destroy() throws Exception {
tearDown();
}
@Override
protected URI getBaseUri() {
return URI.create("http://localhost:9993");
}
@Override
protected Application configure() {
RestApplication application = new RestApplication();
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true);
properties.put("contextConfigLocation", "classpath:spring-context-test.xml");
application.setProperties(properties);
application.register(this);
return application;
}
}
因此,问题在于我需要从测试中访问Spring bean,以使用一些数据填充数据库。
球衣版本是2.6
我也在这里找到了类似的问题
但这与Jersey 1.x有关,因此不适用于Jersey 2.x
有人能指出我正确的方向吗?
通常情况下,我只是说要使用模拟,但是在某些情况下,您可能需要在测试类中公开服务。
为了做到这一点而没有任何“丑陋的hack”,您将需要在ServiceLocator
上获得一个句柄(类似于Spring的ApplicationContext
)。 当Jersey应用启动时,来自ApplicationContext
所有Spring服务都将通过HK2的Spring桥放入ServiceLocator
。
问题是JerseyTest
不会以任何方式公开ServiceLocator
。 我想得到它的唯一方法是创建自己的TestContainerFactory
,并创建ApplicationHandler
,从而公开ServiceLocator
。
如果您不知道自己在做什么,尝试实现自己的TestContainerFactory
并不是在公园里散步。 最简单的方法是查看Jersey的InMemoryTestContainerFactory
的源代码。 如果查看内部类InMemoryTestContainer
的构造函数,您会看到它正在创建ApplicationHandler
。 这是通过appHandler.getServiceLocator()
公开ServiceLocator
的appHandler.getServiceLocator()
。
因此,如果复制了该类并公开了ServiceLocator
,则可以创建JerseyTest
扩展,然后调用ServiceLocator.inject(Object)
方法来注入测试类。
public abstract class AbstractServiceLocatorAwareJerseyTest extends JerseyTest {
private final ServiceLocatorAwareInMemoryTestContainerFactory factory
= new ServiceLocatorAwareInMemoryTestContainerFactory();
private ServiceLocator locator;
@Override
public TestContainerFactory getTestContainerFactory() {
return factory;
}
@Before
@Override
public void setUp() throws Exception {
super.setUp();
this.locator = factory.getServiceLocator();
if (injectTestClass()) {
this.locator.inject(this);
}
}
public boolean injectTestClass() {
return true;
}
public ServiceLocator getServiceLocator() {
return locator;
}
}
并且,如果出于任何原因需要它, ServiceLocator
还具有ApplicationContext
,如果需要,还可以将其公开给测试类。
如果您想看一下,我将GitHub项目和一个完整的实现一起进行了测试。
尽管OP对这个问题的回答是可行的,但我相信它可行的事实是一个错误。 我最初在OP发布他们的答案后删除了这个答案,但是经过一些测试,我相信该解决方案是一个错误,因此对于那些不喜欢警告1的人,我已取消删除该帖子。
1.“警告:在SERVER运行时中注册的提供者SimpleTest不会实现在SERVER运行时中适用的任何提供者接口。由于约束配置问题,提供者SimpleTest将被忽略。”
解决方法非常简单。 我补充说:
@Autowired
private Repository repository;
到AbstractJerseyTest,并且该字段在测试启动过程中自动自动接线。 我不知道有关其工作原理的详细信息,但似乎当我在REST应用程序中注册测试实例时
application.register(this);
它会自动为测试中的所有bean自动布线。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.