2016-01-26 34 views
0

我目前玩springockito-annotations,這需要@RunWith@ContextConfiguration註釋才能工作。我想將這些註釋放在我的測試的超類上,但似乎無法使其工作。@ContextConfiguration不會繼承與Springockito

超類:

@RunWith(SpringJUnit4ClassRunner.class) 
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class}) 
@ContextConfiguration(loader = SpringockitoContextLoader.class, locations = "classpath:spring/test-context.xml") 
public class MyTestSuperclass { 
    //... 

實施例的TestClass:

public class MyTest extends MyTestSuperclass { 
    @Inject 
    @ReplaceWithMock 
    private MyService myService; 
    //... 

有了這個代碼,myService不與一個模擬代替。

但是,如果我將其更改爲...

@ContextConfiguration 
public class MyTest extends MyTestSuperclass { 
    //... 

...它的工作原理。

有沒有辦法避免必須將@ContextConfiguration添加到我的所有測試類?這可能已在更新版本的Spring/Spring-tests中修復?從我可以告訴它能夠繼承超類中的locations部分而不註釋子類,但loader部分在子類中沒有註解的情況下不起作用。我正在使用版本3.2.1.RELEASE的Spring-test

下面是一個示例工程中的,顯示錯誤:

http://www.filedropper.com/springockitobug

+0

'彈簧test'因爲Spring框架3.0已經支持裝載機的繼承。所以你絕對不需要重新聲明一個空的'@ ContextConfiguration'。 Springockito實現可能存在問題。您是否願意發佈一個最小示例項目來演示此行爲(例如,在GitHub上)? –

+0

我認爲罪魁禍首是'springockito-annotations',當註釋類有一個未註釋的超類時,我也遇到了問題,在這些情況下,@ @ ReplaceWithMock沒有工作。 – Tobb

+0

增加了一個最小化的項目。在最小的項目中無法重現上述評論中的錯誤,所以一定是由於其他原因。 – Tobb

回答

2

這是由於bug in Springockito

@ContextConfiguration實際上是繼承的,自從它在Spring 2.5中引入以來就一直如此。此外,配置的loader(即在這種情況下爲SpringockitoContextLoader)也是繼承的,自從Spring 3.0以來就一直如此。

的這裏的問題是,SpringockitoContextLoader正確處理聲明類(即,標註有@ContextConfiguration類),而不是實際測試類(其可以是繼承的@ContextConfiguration聲明一個子類)。

經過徹底的調試後,事實證明該解決方案非常簡單(實際上比原始的SpringockitoContextLoader實施更簡單)。

以下PatchedSpringockitoContextLoader應該可以正常工作,作爲破損的SpringockitoContextLoader的直接替換。

import org.kubek2k.springockito.annotations.internal.Loader; 

import org.springframework.context.ConfigurableApplicationContext; 
import org.springframework.context.support.GenericApplicationContext; 
import org.springframework.test.context.MergedContextConfiguration; 
import org.springframework.test.context.support.GenericXmlContextLoader; 

public class PatchedSpringockitoContextLoader extends GenericXmlContextLoader { 

    private final Loader loader = new Loader(); 

    @Override 
    protected void prepareContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) { 
     super.prepareContext(context, mergedConfig); 
     this.loader.defineMocksAndSpies(mergedConfig.getTestClass()); 
    } 

    @Override 
    protected void customizeContext(GenericApplicationContext context) { 
     super.customizeContext(context); 
     this.loader.registerMocksAndSpies(context); 
    } 

} 

問候,

山姆(Spring的TestContext框架的作者)

0

代替使用一個超類的,使用註解。

例如:

@RunWith(SpringJUnit4ClassRunner.class) 
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class}) 
@ContextConfiguration(loader = SpringockitoContextLoader.class, locations = "classpath:spring/test-context.xml") 
@Target(ElementType.TYPE) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface TestConfiguration { 
} 

然後,註釋您的測試類,

@TestConfiguration 
public class MyTest { 
    @Inject 
    @ReplaceWithMock 
    private MyService myService; 
    //... 

IDE的語法高亮可能會抱怨沒有被允許噴射,這取決於您使用,但我最初的測試有這個工作

+0

我試圖避免註釋每個測試類,將'@ ContextConfiguration'更改爲'@ TestConfiguration'並沒有真正的幫助(除非我可以把'@ TestConfiguration'放在超類上,並避免它在子類上。)但是不知道這是可能的,很高興知道:) – Tobb

+0

我沒有設置類框架來確認,但是您可以將'@ Inherited'放在'@ TestConfiguration'的定義中。然後把它放在你的基類上 - 如果這樣的話,只要說,我就可以更新答案。 – Farrell

+1

供參考:'@ RunWith'不能用作元註釋。這僅僅是JUnit不支持的。因此,我不確定你在聲稱的作品。用你的例子,將使用標準的'JUnit4'運行程序,而不是'SpringJUnit4ClassRunner'。 –