Paul C
Paul C

Reputation: 8497

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

}

Upvotes: 2

Views: 5612

Answers (3)

Eron Wright
Eron Wright

Reputation: 1060

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.

Upvotes: 1

whaley
whaley

Reputation: 16265

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).

Upvotes: 7

GreyBeardedGeek
GreyBeardedGeek

Reputation: 30088

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.

Upvotes: 1

Related Questions