Java 如何从JerseyTest子类访问Springbean
下面是我的抽象类,它从给定的Spring上下文开始:Java 如何从JerseyTest子类访问Springbean,java,spring,testing,jersey,jersey-2.0,Java,Spring,Testing,Jersey,Jersey 2.0,下面是我的抽象类,它从给定的Spring上下文开始: public abstract class AbstractJerseyTest extends JerseyTest { public void setUp() throws Exception { super.setUp(); } @AfterClass public void destroy() throws Exception { tearDown(); } @Override protected URI get
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;
}
}
公共抽象类AbstractJerseyTest扩展了JerseyTest{
public void setUp()引发异常{
super.setUp();
}
@下课
public void destroy()引发异常{
撕裂();
}
@凌驾
受保护的URI getBaseUri(){
返回URI.create(“http://localhost:9993");
}
@凌驾
受保护的应用程序配置(){
RestApplication application=新的RestApplication();
映射属性=新的HashMap();
properties.put(ServerProperties.BV_在_响应中发送_错误,true);
put(“contextConfigLocation”,“classpath:spring context test.xml”);
应用程序。设置属性(属性);
申请登记(本);
退货申请;
}
}
所以,问题是我需要从测试中访问Springbean,用一些数据填充数据库
泽西版本是2.6
我还发现了一个类似的问题
但它与Jersey 1.x有关,所以它不适用于Jersey 2.x
有人能给我指出正确的方向吗?通常在您的情况下,我只会说使用mock,但在某些情况下,您可能需要在测试类中公开服务
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
(类似于Spring的ApplicationContext
)的句柄。当Jersey应用程序启动时,来自ApplicationContext
的所有Spring服务将通过HK2的Spring bridge放入ServiceLocator
问题在于JerseyTest
不会以任何方式暴露ServiceLocator
。我能想到的唯一方法是创建自己的TestContainerFactory
,并创建ApplicationHandler
,它公开了ServiceLocator
如果您不知道自己在做什么,那么尝试实现自己的TestContainerFactory
并不是一件轻而易举的事。最简单的方法就是查看Jersey的源代码。如果查看内部类InMemoryTestContainer
的构造函数,您将看到它创建了ApplicationHandler
。这就是如何通过appHandler.getServiceLocator()
公开ServiceLocator
因此,如果复制了该类,并公开了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
,如果需要,您还可以将其公开给测试类
如果你想看的话,我把一个完整的实现和测试放在一起
更新 虽然OP对这个问题的回答是有效的,但我相信它有效的事实是一个bug。在OP发布了他们的答案后,我最初删除了这个答案,但是经过一些测试,我相信这个解决方案是一个bug,所以我为那些不喜欢使用该解决方案时得到的警告1的人取消了这篇帖子
一,。“警告:在服务器运行时中注册的提供程序SimpleTest未实现任何适用于服务器运行时的提供程序接口。由于约束配置问题,将忽略提供程序SimpleTest。”解决方案非常简单。 我补充说: 到AbstractJersey测试,此字段在测试启动期间自动连接。我不知道它是如何工作的,但当我在REST应用程序中注册测试实例时
application.register(this);
它会自动连接测试中的所有bean。请查看我发布的答案。有时我会错过显而易见的事情。我甚至没有注意到你注册了测试类。这很有道理。事实上,经过进一步的测试,我相信这是一个错误,这是可行的。这肯定不是一项功能,因为我收到一条日志警告:“警告:在服务器运行时注册的提供程序SimpleTest不会实现任何适用于服务器运行时的提供程序接口。由于约束配置问题,将忽略提供程序SimpleTest。”。你收到同样的警告了吗?我说这是一个bug,因为即使类被注入,它也没有注册为一个可以注入到其他东西中的服务。“我得多调查一下。”皮斯基勒,我没有发现你提到的警告。但是,它可能与记录器设置有关。