2012-08-29 56 views
3

我有我的抽象測試類的代碼段(我知道XmlBeanFactoryClassPathResource已棄用,但它不太可能是問題的情況)。Spring測試@ContextConfiguration和靜態上下文

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration 
public abstract class AbstractIntegrationTest { 

    /** Spring context. */ 
    protected static final BeanFactory context = new XmlBeanFactory(new ClassPathResource(
      "com/.../AbstractIntegrationTest-context.xml")); 

    ... 

} 

它加載默認的測試配置XML文件AbstractIntegrationTest-context.xml(然後我用自動裝配)。我還需要在用@BeforeClass@AfterClass註釋的靜態方法中使用Spring,所以我有一個單獨的上下文變量指向相同的位置。但問題是這是一個單獨的上下文,它將有不同的bean實例。那麼我怎樣才能合併這些上下文,或者我如何從靜態上下文中調用由@ContextConfiguration定義的Spring初始化bean?

我想通過擺脫這些靜態成員的可能的解決方案,但我很好奇,如果我可以做到與代碼相對較小的更改。

回答

6

您是對的,您的代碼將產生兩個應用程序上下文:一個將由@ContextConfiguration註釋開始,緩存和維護。您自己創建的第二個上下文。兩者都沒有多大意義。

不幸的是JUnit是不是非常適合集成測試 - 這主要是因爲你不能有上課前和非靜態方法之後。我看到兩個選擇適合你:

  • 開關 - 我知道這是一個很大的一步

  • 編碼您的安裝/拆除邏輯在一個Spring bean包含在僅在測試的範圍內 - 但隨後它只會在所有測試之前運行一次。

也有不那麼優雅的方法。您可以使用static變量並注入情況下它:

private static ApplicationContext context; 

@AfterClass 
public static afterClass() { 
    //here context is accessible 
} 

@Autowired 
public void setApplicationContext(ApplicationContext applicationContext) { 
    context = applicationContext; 
} 

或者你可以用@DirtiesContext註釋您的測試類,做清理工作在一些測試豆:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration 
@DirtiesContext(classMode = AFTER_CLASS) 
public abstract class AbstractIntegrationTest { 

    //... 

} 

public class OnlyForTestsBean { 

    @PreDestroy 
    public void willBeCalledAfterEachTestClassDuringShutdown() { 
     //.. 
    } 

} 
+0

關於第二選擇。在所有測試之前運行一次並不是一個大問題。事情是,如何做課後*邏輯? – Vic

+0

@Vic:查看我的更新 –

+0

第一個解決方案仍然存在問題:「從* where *獲取應用程序上下文注入?」第二個必須工作。我會嘗試。 – Vic

5

不知道你是否選擇了任何方法在這裏,但我遇到了同樣的問題,並用Spring測試框架的TestExecutionListener以另一種方式解決了這個問題。

beforeTestClassafterTestClass,所以在JUnit中都相當於@BeforeClass@AfterClass

我做的方式:

@RunWith(SpringJUnit4ClassRunner.class) 
@TestExecutionListeners(Cleanup.class) 
@ContextConfiguration(locations = { "/integrationtest/rest_test_app_ctx.xml" }) 
public abstract class AbstractIntegrationTest { 
    // Start server for integration test. 
} 

你需要創建一個擴展AbstractTestExecutionListener類:

public class Cleanup extends AbstractTestExecutionListener 
{ 

    @Override 
    public void afterTestClass(TestContext testContext) throws Exception 
    { 
     System.out.println("cleaning up now"); 
     DomainService domainService=(DomainService)testContext.getApplicationContext().getBean("domainService"); 
     domainService.delete(); 

    } 
} 

通過這樣做,您可以訪問應用程序上下文,做你的設置/用春豆在這裏拆卸。

希望這有助於任何人嘗試像我一樣使用JUnit + Spring進行集成測試。

+0

感謝您的解決方案。據我所知,我確實選擇了Tomasz的方法。 – Vic

相關問題