使用 Spring 和 Maven 进行测试:applicationContext

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10104372/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 05:04:17  来源:igfitidea点击:

Testing with Spring and Maven: applicationContext

springunit-testingmaven

提问by Vladimir Kishlaly

Seems that question old as world, but I still can't find out the solution..

似乎这个问题与世界一样古老,但我仍然找不到解决方案..

I'm trying to run simple test:

我正在尝试运行简单的测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/applicationContext.xml", "/PersonsPopulateTest-context.xml"})
@Transactional
public class PersonsPopulateTest {

Files are at:

文件位于:

src
   main
      resources
           applicationContext.xml

and

src        
   test
      resources
          PersonsPopulateTest-context.xml 

So after building these files are at target/classesand target/test-classes

所以在构建这些文件后,目标/类目标/测试类

But mvn test command still says: Failed to load ApplicationContext

但是 mvn test 命令仍然说:无法加载 ApplicationContext

What official docs say:

什么官方文档说:

@RunWith(SpringJUnit4ClassRunner.class)
// ApplicationContext will be loaded from "/applicationContext.xml" and "/applicationContext-test.xml"
// in the root of the classpath
@ContextConfiguration(locations={"/applicationContext.xml", "/applicationContext-test.xml"})
public class MyTest {
    // class body...
}

Where did I go wrong?

我哪里做错了?

Thanks, Vlaidimir

谢谢,弗拉基米尔

UPDATE. surefire-reports:

更新。万无一失的报告:

java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:157)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:290)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access
    <!-- Add this directly after the <build>-opening tag -->
    <resources>
        <resource>
            <filtering>true</filtering>
            <directory>src/test/resources</directory>
            <includes>
                <include>**/*.properties</include>
            </includes>
            <excludes>
                <exclude>**/*local.properties</exclude>
            </excludes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>
0(ParentRunner.java:42) at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:184) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) at org.junit.runners.ParentRunner.run(ParentRunner.java:236) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53) at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123) at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164) at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110) at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175) at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107) at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68) Caused by: java.lang.IllegalArgumentException: Can not load an ApplicationContext with a NULL 'contextLoader'. Consider annotating your test class with @ContextConfiguration. at org.springframework.util.Assert.notNull(Assert.java:112) at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:117) at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:148) ... 30 more

采纳答案by Vladimir Tsvetkov

I think Maven simply didn't include the XML file from main/resources.

我认为 Maven 根本没有包含来自 main/resources 的 XML 文件。

You could try to specify explicitly what to include in the pom.xml.

您可以尝试明确指定要包含在 pom.xml 中的内容。

Let me know if the following configuration has worked:

让我知道以下配置是否有效:

@ContextConfiguration(locations={"classpath:**/test-context.xml"})

This is something I use in your case. You can edit this if you don't have properties files to be included.

这是我在你的情况下使用的东西。如果您没有要包含的属性文件,您可以编辑它。

回答by Ahamed Mustafa M

My test context file is under src\test\resources\springfolder. I managed to load the context with

我的测试上下文文件位于src\test\resources\spring文件夹下。我设法加载了上下文

ClassPathXmlApplicationContext appContext=new ClassPathXmlApplicationContext(new String[]{"classpath:spring/application-context.xml","classpath:spring/model-context.xml"});

But reference (in test-context.xml) to the application-context.xml which is under src\main\resources\springfolder failed

但是对src\main\resources\spring文件夹下的 application-context.xml 的引用(在 test-context.xml 中)失败

I managed to load the application-context by creating a ClassPathXmlApplicationContext in the test class with

我设法通过在测试类中创建一个 ClassPathXmlApplicationContext 来加载应用程序上下文

@ContextConfiguration(locations = { "classpath:*/application-context.xml" })

Let me know if this helps or might create any other issues.

让我知道这是否有帮助或可能会产生任何其他问题。

回答by borchvm

your application context must be included in classpath and put * :

您的应用程序上下文必须包含在类路径中并放置 * :

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:**/PersonsPopulateTest-context.xml"})
@Transactional
public class PersonsPopulateTest {

}

回答by Tony Vu

I think best practice is to put your application context file for testing PersonsPopulateTest-context.xml under src/test/resources. This file will be copied into target/test-classesand you can refer to it in your test class as below:

我认为最佳实践是将用于测试 PersonsPopulateTest-context.xml 的应用程序上下文文件放在 src/test/resources 下。这个文件将被复制到目标/测试类,你可以在你的测试类中引用它,如下所示:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"file:src/main/resources/applicationContext.xml"})
@Transactional
public class PersonsPopulateTest {

}

If you still want to refer to applicationContext.xml under src/main/resources, then you have to include it as follow:

如果你还想引用 src/main/resources 下的 applicationContext.xml,那么你必须包含它,如下所示:

<!-- Add this directly after the <build>-opening tag in the your pom-->
            <testResources>
                <testResource>
                    <directory>src/test/resources</directory>
                    <filtering>true</filtering>
                    <includes>
                        <include>**/*.xml</include>
                        <include>**/*.properties</include>
                    </includes>
                </testResource>
            </testResources>

It worked for me.

它对我有用。

回答by Daniela

<plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.10</version>
            <configuration>
                <additionalClasspathElements>
                    <additionalClasspathElement>${project.basedir}/src/test/resources</additionalClasspathElement>
                </additionalClasspathElements>      
            </configuration>

回答by lekant

For some reason, I had the same issue and it worked when I ran maven test with the JDK6 instead of JDK8 (in my case this is a legacy application)

出于某种原因,我遇到了同样的问题,当我使用 JDK6 而不是 JDK8 运行 maven 测试时它起作用了(在我的情况下,这是一个遗留应用程序)

If it helps anyone.

如果它帮助任何人。

回答by Ambarish Hazarnis

I faced the same problem. For me the test was running successfully via eclipse. However, when I ran mvn test, it was giving me error: Failed to load ApplicationContext

我遇到了同样的问题。对我来说,测试是通过 eclipse 成功运行的。但是,当我运行时mvn test,它给了我错误:无法加载 ApplicationContext

Fix: Added the src/test/resources directory to classpath of surefire plugin as-

修复:将 src/test/resources 目录添加到surefire插件的类路径中作为-

<build>
    <resources>
        <resource>
            <directory>${project.basedir}/src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
    <testResources>
        <testResource>
            <directory>${project.basedir}/src/test/java/resources</directory>
            <filtering>true</filtering>
        </testResource>
    </testResources>
</build>

Adding classpath to SureFire

将类路径添加到 SureFire

Hope it helps.

希望能帮助到你。

回答by Vladimir Sorokin

I had the same problem, all files were successfully copied to target/classesand target/test-classes, still springcould not find them.

我遇到了同样的问题,所有文件都成功复制到target/classestarget/test-classes,但spring仍然找不到它们。

Problem disappeared when I explicitly specified versions for maven-surefire-pluginand maven-resources-pluginin pom

当我在pom 中maven-surefire-pluginmaven-resources-plugin明确指定版本时,问题消失了

回答by Alexander Volkov

UPDATED: Actually in my case the problem was in Compile on Saveoption enabled. I use Netbeans, and the option was set to For test execution only. This value compiles changed files and replaces resources with new files. However, due to usage of application resources additionally to test resources, For test execution onlyproduces incorrectly generated resources in targetfolder.

更新:实际上在我的情况下,问题在于Compile on Save启用了选项。我使用 Netbeans,并且该选项设置为For test execution only. 此值编译更改的文件并用新文件替换资源。但是,由于除了测试资源之外还使用了应用程序资源,For test execution only会在target文件夹中产生错误生成的资源。

Changing Compile on Save=For test execution only

改变 Compile on Save=For test execution only

to Compile on Save=Disablefixes the problem.

Compile on Save=Disable解决问题。

The text below is also correct, but sometimes does not work. It was working only till I restarted Netbeans IDE. However, the details of the reason of the problem are correct, hence, I prefer to leave the test.

下面的文字也是正确的,但有时不起作用。它只在我重新启动 Netbeans IDE 之前工作。但是,问题原因的详细信息是正确的,因此我宁愿离开测试。



OLD: In my situation I have appContext-test.xmlin src/main/resources. When I change any code and launch one unit test (not all of them) it recompiles and correctly executed. But if I launch same unit test again it is failed with the java.lang.IllegalStateException: Failed to load ApplicationContext.

OLD:在我的情况我都appContext-test.xmlsrc/main/resources。当我更改任何代码并启动一个单元测试(不是全部)时,它会重新编译并正确执行。但是,如果我再次启动相同的单元测试,则java.lang.IllegalStateException: Failed to load ApplicationContext.

I have changed pom.xmlfrom

我已经pom.xml

<build>
    <resources>
        <resource>
            <directory>${project.basedir}/src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
    <testResources>
        <testResource>
            <directory>${project.basedir}/src/main/resources</directory>
            <filtering>true</filtering>
        </testResource>
        <testResource>
            <directory>${project.basedir}/src/test/java/resources</directory>
            <filtering>true</filtering>
        </testResource>
    </testResources>
</build>

to

database.url = ${database.url}
database.username = ${database.username}
database.password = ${database.password}

and now all work fine.

现在一切正常。

The error was dueto appContext-test.xmluses src/main/resources/my.propertiesfile with a lot of variables like

错误是由于appContext-test.xml使用src/main/resources/my.properties有很多的变量,如文件

##代码##

that are filled during a build. However, if you skip src/main/resourcesin testResource, then my.propertiesis added to target/classes/my.propertiesas is, i.g. without a substitution. This file of course breaks the context.

在构建期间填充。但是,如果你跳过src/main/resourcestestResource,然后my.properties加入到target/classes/my.properties原样,没有一个替代灌胃。这个文件当然打破了上下文。

PS: You can remove ${project.basedir}/- it is my custom thing.

PS:您可以删除${project.basedir}/- 这是我的自定义内容。