如何通过 TestRule 检索 Spring ApplicationContext

How retrieve the Spring ApplicationContext through TestRule

我想知道是否可以通过 TestRule.

检索 ApplicationContext

这里TestRule使用了一种方法来避免测试类之间的层次结构,目的是重用基础设施配置但是 在这种情况下,所需的结构 @Beans 已经由 Spring 创建。

为了简化要共享的代码,假设我们需要检索 Environment 对象。

我试过这两种方法:

一个

@WebAppConfiguration
@ContextConfiguration(classes={RootApplicationContext.class, ServletApplicationContext.class})
public class ManolitoRule implements TestRule {

    @Autowired
    private Environment environment;

    private static final Logger logger = LoggerFactory.getLogger(ManolitoRule.class.getSimpleName());

    @Override
    public Statement apply(Statement base, Description description) {

        if(environment == null) {
            logger.error("NULL");
        }
        else {
            logger.info("Profiles: {}", Arrays.toString(environment.getActiveProfiles()));
        }

        return new Statement() {

                //The @Before configuration should go here now
                ...


            }


        };


    }

}

public class ManolitoTest {

    private static final Logger logger = LoggerFactory.getLogger(ManolitoTest.class.getSimpleName());

    @Rule
    public ManolitoRule manolitoRule = new ManolitoRule();

    @Test
    public void manolitoTest() {

        ...

    }

}

environmentnull

两个

public class ManolitoRule implements TestRule {

    private final Environment environment;

    public ManolitoRule(Environment environment) {
        this.environment = environment;
    }

    private static final Logger logger = LoggerFactory.getLogger(ManolitoRule.class.getSimpleName());

    @Override
    public Statement apply(Statement base, Description description) {

        if(environment == null) {
            logger.error("NULL");
        }
        else {
            logger.info("Profiles: {}", Arrays.toString(environment.getActiveProfiles()));
        }

        return new Statement() {

            //The @Before configuration should go here now    
            ....


        };


    }

}

@WebAppConfiguration
@ContextConfiguration(classes={RootApplicationContext.class, ServletApplicationContext.class})
@TestExecutionListeners(listeners={LoggingTestExecutionListener.class}, mergeMode=MergeMode.MERGE_WITH_DEFAULTS)
public class ManolitoTest {

    private static final Logger logger = LoggerFactory.getLogger(ManolitoTest.class.getSimpleName());

    @Autowired
    private Environment environment;

    @Rule
    public ManolitoRule manolitoRule = new ManolitoRule(environment);

    @Test
    public void manolitoTest() {

        ...

    }

}

同样 environmentnull

是否存在完成此配置的正确配置?

我的印象是 JUnitSpring Framework 之间的生命周期是造成这种情况的原因。

注意:如果使用摘要class,一切正常。但是请考虑避免层次结构和 chain @Rule 的场景,例如 ManolitoRuleSpringClassRuleSpringMethodRule[=30= 一起工作]

你试过吗

@Autowired 
private Environment env;

编辑: 也尝试添加这个

@RunWith(SpringJUnit4ClassRunner.class)

方法 Two 接近可行的解决方案,只需要进行以下更改。

  1. @RunWith(SpringRunner.class).
  2. 注释测试 class
  3. 在测试的 ApplicationContext.
  4. 中将 ManolitoRule 的实例配置为 bean
  5. @Autowired注释ManolitoRule构造函数。
  6. 将测试class中的manolitoRule字段注释为@Rule@Autowired.

注意:此技术 不能 与 Spring 规则(SpringClassRuleSpringMethodRule)结合使用。此技术仅适用于 SpringRunner.