22

I have some problems with dependency injection (Spring autowiring) and maven-surefire. The following test works without problems when run in eclipse with TestNG: The service-object is injected, then the @BeforeClass-method is called.

@TransactionConfiguration(defaultRollback=false)
@ContextConfiguration(locations={"/testContext.xml"})
public class MyServiceTest extends AbstractTransactionalTestNGSpringContextTests {


@Autowired
private MyService service;

@BeforeTest
public void setup() {
    System.out.println("*********************"+service);
    Assert.assertNotNull(service);
}

However, when I run the very same testcase with maven-surefire, first setup() is called, which causes the test to fail:

[INFO] --- maven-surefire-plugin:2.7.2:test (default-test) @ myserver ---
[INFO] Surefire report directory: D:\...
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running TestSuite
**************************null
2011-03-04 11:08:57,462 DEBUG  ionTestExecutionListener.prepareTestInstance  - Performing dependency injection for test context [[TestContext@1fd6bea...
2011-03-04 11:08:57,462 DEBUG  ractGenericContextLoader.loadContext          - Loading ApplicationContext for locations [classpath:/testContext.xml].

How can I solve this problem? If I replace @BeforeClass with @Test it works in maven as in TestNG's eclipse plugin.

maven-surefire-plugin:2.7.2

Eclipse: Helios Service Release 1

jdk1.6.0_14

TestNG: 5.14.10

Sean Patrick Floyd
  • 274,607
  • 58
  • 445
  • 566
thofoer
  • 221
  • 1
  • 2
  • 3
  • I don't know very much about maven-surefire and its integration with spring. But, to have spring components injected, an object also must be initialized by spring. – bluefoot Mar 04 '11 at 10:41
  • I had a similar issue but JUnit: I was starting/stopping Jetty in `@BeforeClass`/`@AfterClass` annotated methods in a test class, and it didn't work, because autowiring had not happened yet. – MarcoS Mar 04 '11 at 12:59

5 Answers5

23

Additionally, until this issue is fixed, if things still aren't working for you after following the previous advice OR you do not wish your code to be executed before every single method, then add the following code to your test class:

@Override
@BeforeSuite
protected void springTestContextPrepareTestInstance() throws Exception {
    super.springTestContextPrepareTestInstance();
}

This ensures that the Spring Context will be prepared before your @BeforeClass methods are executed.

*note, I posted this answer since in the title you're asking about @BeforeClass, even though there is no usage of @BeforeClass in your sample code.

Aidan O
  • 519
  • 4
  • 10
  • Hats off to you, you saved me :) – ernitingoel Oct 12 '16 at 15:40
  • Check this issue out, https://jira.spring.io/browse/SPR-4072?focusedCommentId=90429&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-90429 – Dehan Oct 17 '17 at 07:43
12

Use @BeforeMethod, not @BeforeTest.

naXa
  • 26,677
  • 15
  • 154
  • 213
Cedric Beust
  • 14,944
  • 2
  • 49
  • 54
7

I agree with Cedric: use @BeforeMethod instead of @BeforeTest, since Spring's dependency injection occurs in an @BeforeClass method.

  • Sam (author of the Spring TestContext Framework ;) )
Saikat
  • 8,190
  • 12
  • 69
  • 94
Sam Brannen
  • 24,249
  • 2
  • 75
  • 114
1

Use @PostConstruct not @BeforeXXX

Ran Adler
  • 3,083
  • 25
  • 26
  • There was a problem when I use @PostConstruct: the static method use this annotation was invoked before every test case , but what I wanted is to be invoked only once. – Allen Jun 26 '15 at 05:27
0

Check if you have spring-asm dependency as well. If you have one it will conflict with spring-core dependency. I removed the asm dependency and this worked for me.

Akshay
  • 508
  • 1
  • 5
  • 14