Spring doesn't autowire fields when runner inv

2019-08-02 08:19发布

问题:

I have following test:

@RunWith(Parameterized.class)
@SpringBootTest
@ContextConfiguration(classes = MyConfig.class)
public class OrderPlacementCancelTest {
    @Autowired
    private TestSessionsHolderPerf sessionsHolder;

    @ClassRule
    public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();

    @Rule
    public final SpringMethodRule springMethodRule = new SpringMethodRule();

    private CommonCredentialSetter commonCredentialSetter;

    @Before
    public void login() throws InterruptedException {        
        int attempts = 0;
        while (!sessionsHolder.isClientLoggedIn() && attempts < 3) {
            Thread.sleep(1000);
            ++attempts;
        }

    }
     @Parameterized.Parameters()
     public static Collection<Object[]> data() {
        ...
     }

and following runner:

@Test
    public void test() throws Exception {
        Class[] cls = {OrderPlacementCancelTest.class};
        Result result = JUnitCore.runClasses(new ParallelComputer(false, true), cls);
        logger.info("Failure count={}", result.getFailureCount());
        for (Failure failure : result.getFailures()) {
            logger.error(failure.getTrace());
        }
    }

When I start test via runner I see that sometimes method login marked as @Before throws NullPointerException because sessionsHolder is null.

How can I avoid it?

回答1:

It seems that @Parameterized does not mix well with junit rules. One option would be to replace the Rule by performing the logic in the constructor of the parameterized test class, or calling a setup method at the beginning of your test methods.

In either case you can use TestContextManager to populate your test class with the @AutoWired values like this:

private TestContextManager testContextManager;

@Before
public void login() throws Exception {
    testContextManager = new TestContextManager(getClass());
    testContextManager.prepareTestInstance(this);