![](/img/trans.png)
[英]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.