views:

320

answers:

3

I try to setup a project with spring-test using TestNg in Maven. The code is like:

@ContextConfiguration(locations={"test-context.xml"})
public class AppTest extends AbstractTestNGSpringContextTests {

    @Test
    public void testApp() {
        assert true;
    }
}

A test-context.xml simply defined a bean:

<bean id="app" class="org.sonatype.mavenbook.simple.App"/>

I got error for Failed to load ApplicationContext when running mvn test from command line, seems it cannot find the test-context.xml file; however, I can get it run correctly inside Eclipse (with TestNg plugin).

So, test-context.xml is under src/test/resources/, how do I indicate this in the pom.xml so that 'mvn test' command will work? Thanks,

UPDATE:

Thanks for the reply. Cannot load context file error was caused by I moved the file arround in different location since I though the classpath was the problem. Now I found the context file seems loaded from the Maven output, but the test is failed:

Running TestSuite
May 25, 2010 9:55:13 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [test-context.xml]
May 25, 2010 9:55:13 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.GenericApplicationContext@171bbc9: display name [org.springframework.context.support.GenericApplicationContext@171bbc9]; startup date [Tue May 25 09:55:13 PDT 2010]; root of context hierarchy
May 25, 2010 9:55:13 AM org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
INFO: Bean factory for application context [org.springframework.context.support.GenericApplicationContext@171bbc9]: org.springframework.beans.factory.support.DefaultListableBeanFactory@1df8b99
May 25, 2010 9:55:13 AM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1df8b99: defining beans [app,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor]; root of factory hierarchy
Tests run: 3, Failures: 2, Errors: 0, Skipped: 1, Time elapsed: 0.63 sec <<< FAILURE!

Results :

Failed tests: 
  springTestContextBeforeTestMethod(org.sonatype.mavenbook.simple.AppTest)
  springTestContextAfterTestMethod(org.sonatype.mavenbook.simple.AppTest)

Tests run: 3, Failures: 2, Errors: 0, Skipped: 1

If I use spring-test version 3.0.2.RELEASE, the error becomes:

org.springframework.test.context.testng.AbstractTestNGSpringContextTests.springTestContextPrepareTestInstance() is depending on nonexistent method null

Here is the structure of the project:

simple
|-- pom.xml
`-- src
    |-- main
    |   `-- java
    `-- test
        |-- java
        `-- resources
            |-- test-context.xml
            `-- testng.xml

testng.xml:

<suite name="Suite" parallel="false">
  <test name="Test">
    <classes>
      <class name="org.sonatype.mavenbook.simple.AppTest"/>
    </classes>
  </test>
</suite>

test-context.xml:

 <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
         http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
    default-lazy-init="true">
    <bean id="app" class="org.sonatype.mavenbook.simple.App"/>
 </beans>

In the pom.xml, I add testng, spring, and spring-test artifacts, and plugin:

<dependency>
  <groupId>org.testng</groupId>
  <artifactId>testng</artifactId>
  <version>5.1</version>
  <classifier>jdk15</classifier>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring</artifactId>
  <version>2.5.6</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId> 
    <version>2.5.6</version> 
    <scope>test</scope> 
</dependency>

<build>
<finalName>simple</finalName>
<plugins>
  <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
      <source>1.6</source>
      <target>1.6</target>
    </configuration>
  </plugin>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>   
      <suiteXmlFiles>
        <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
      </suiteXmlFiles>
    </configuration>
  </plugin>
</plugins>

Basically, I replaced 'A Simple Maven Project' Junit with TestNg, hope it works.

UPDATE:

I think I got the problem (still don't know why) - Whenever I extends AbstractTestNGSpringContextTests or AbstractTransactionalTestNGSpringContextTests, the test will failed with this error:

Failed tests:
  springTestContextBeforeTestMethod(org.sonatype.mavenbook.simple.AppTest)
  springTestContextAfterTestMethod(org.sonatype.mavenbook.simple.AppTest)

So, eventually the error went away when I override the two methods. I don't think this is the right way, didn't find much info from spring-test doc. If you know spring test framework, please shred some light on this.

+2  A: 

Add classpath in front of the filename. Then it will search in the root folder of all source folders.

@ContextConfiguration(locations={"classpath:test-context.xml"})
Espen
I don't understand why you have to add the `classpath:`, both the test and `test-context.xml` are in the same location (`target/test-classes`), what are the other sources folders that should be searched?
Pascal Thivent
I also understand that the classes and resources are copied to the target folder. I just tried to answer how you can be sure that the Spring container will scan after the context in the root folder. Without `classpath:`, Spring will start scanning in the package with the test class. I hope this clarifies what I tried to say.
Espen
Ok, got it now, thanks for the clarification. But I wonder why it works under Eclipse without `classspath:`
Pascal Thivent
I'm not sure exactly how Maven and TestNg do the job. I'm using Ant and JUnit. But my tip will at least remove one uncertainty about where Spring will look for the context.
Espen
Actually, I don't think this answers the question.
Pascal Thivent
A: 

A shot in the dark, since I haven't seen your Java code: are you sure you are using @BeforeMethod and not @BeforeTest?

Cedric Beust
Class App is just a dummy class. The test java code was shown at the beginning of this post: @ContextConfiguration(locations={"/test-context.xml"}) public class AppTest extends AbstractTestNGSpringContextTests { @Test public void testApp() { assert true; } } There is on one @Test method, nothing else.
joejax
A: 

I had the same problem with Spring 2.5.6. I solved using testng 5.5.

The version I was using (testng 5.1) had the same behavior: the test runs fine inside of Eclipse, but it can not find the context from the command line.

Replacing testng with testng 2.5.6 the problem is gone. The is valid only with Spring 2.5.6

Pablo Alcaraz