@ContextConfiguration 不继承 Springockito

@ContextConfiguration is not inherited with Springockito

我目前正在使用 springockito-annotations,这需要 @RunWith@ContextConfiguration 注释才能工作。我想将这些注释放在我的测试的超类上,但似乎无法正常工作。

超类:

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

示例测试类:

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

使用此代码,myService 不会被模拟替换。

但是,如果我把它改成...

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

...有效。

有没有办法避免将 @ContextConfiguration 添加到我的所有测试 类?这可能已在更新版本的 Spring/Spring-tests 中修复了吗?据我所知,它能够从超类继承 locations 部分而无需注释子类,但是 loader 部分在子类中没有注释的情况下不起作用。我使用的是 Spring-test 的 3.2.1.RELEASE 版本。

这是一个显示错误的示例项目:

http://www.filedropper.com/springockitobug

不要使用超级 class,而是使用注释。

例如:

@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 {
}

然后,用

注释你的测试 classes
@TestConfiguration 
public class MyTest  {
    @Inject
    @ReplaceWithMock
    private MyService myService;
    //...

IDE 的语法突出显示可能会抱怨不允许注入,具体取决于您使用的是哪个,但我的初始测试可以正常工作

这是由于bug in Springockito

@ContextConfiguration 实际上是继承的,自从 Spring 2.5 引入以来一直如此。此外,配置的loader(即本例中的SpringockitoContextLoader)也被继承,自Spring 3.0.

以来一直如此。

这里的问题是 SpringockitoContextLoader 错误地处理了 声明的 class(即用 [=11 注释的 class =]) 而不是实际的 test class(可以是继承 @ContextConfiguration 声明的 subclass)。

经过彻底调试,发现解决方案很简单(实际上比原来的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);
    }

}

此致,

Sam(Spring TestContext Framework 的作者)