2016-01-26 33 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'。 –