简体   繁体   中英

Spring's @ContextConfiguration test configuration in a testng class is creating beans only once per test class, not per test

Given a testng class that uses spring's test utility annotation ContextConfiguration to create beans, the beans are only created once for the life of the test class.

Before using this, I always used the @BeforeMethod to rebuild everything before each @Test method.

My question: Is there a way to have spring rebuild the beans for each @Test method?

//The beans are unfortunately created only once for the life of the class.
@ContextConfiguration( locations = { "/path/to/my/test/beans.xml"})
public class Foo {

    @BeforeMethod
    public void setUp() throws Exception {
        //I am run for every test in the class
    }

    @AfterMethod
    public void tearDown() throws Exception {
        //I am run for every test in the class
    }

    @Test
    public void testNiceTest1() throws Exception {    }

    @Test
    public void testNiceTest2() throws Exception {    }

}

If you want the context to be reloaded on each test run, then you ought to be extending AbstractTestNGSpringContextTests and using the @DiritesContext annotation in addition to @ContextConfiguration. An example:

@ContextConfiguration(locations = {
        "classpath:yourconfig.xml"
})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class YourTestClass extends AbstractTestNGSpringContextTests {
 //magic
}

A classmode of Context.ClassMode.AFTER_EACH_TEST_METHOD will cause spring to reload the context after each test method is called. You can also use DirtiesContext.ClassMode.AFTER_CLASS to reload the context before each test class (useful to be used on an superclass for all spring enabled test classes).

Your old @BeforeMethod is probably the right way to go.

@ContextConfiguration is intended to inject beans at the class-level - in other words, it's working exactly as designed.

Another possibility is to use prototype-scoped beans. Each time the test class is instantiated, prototype-scope beans would be instantiated and wired up.

Note that JUnit and TestNG use different logic as to when to instantiate the test class. JUnit creates a new instance for every method, TestNG reuses the test instance. Given that the question is about TestNG, you'd need to factor your tests into many test classes to achieve the overall effect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM