簡體   English   中英

如何從JerseyTest子類訪問Spring Bean

[英]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()公開ServiceLocatorappHandler.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項目和一個完整的實現一起進行了測試。


UPDATE

盡管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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM