如何为Spring Test创建TestContext?

时间:2022-10-18 21:28:51

I have a relatively small Java library that implements a few dozen beans (no database or GUI). I have created a Spring Bean configuration file that other Java projects use to inject my beans into their stuff.

我有一个相对较小的Java库,它实现了几十个bean(没有数据库或GUI)。我创建了一个Spring Bean配置文件,其他Java项目使用它来将我的bean注入其中。

I am now for the first time trying to use Spring Test to inject some of these beans into my junit test classes (rather than simply instantiating them).

我现在第一次尝试使用Spring Test将一些bean注入我的junit测试类(而不是简单地实例化它们)。

I am doing this partly to learn Spring Test and partly to force the tests to use the same bean configuration file I provide for others.

我这样做部分是为了学习Spring Test,部分是为了强制测试使用我为其他人提供的相同bean配置文件。

In the Spring documentation is says I need to create an application context using the "TestContext" class that comes with Spring. I believe this should be done in a spring XML file that I reference via the @ContextConfiguration annotation on my test class.

在Spring文档中说我需要使用Spring附带的“TestContext”类创建应用程序上下文。我相信这应该在一个spring XML文件中完成,我通过我的测试类上的@ContextConfiguration注释来引用它。

@ContextConfiguration({"/test-applicationContext.xml"})

However, there is no hint as to what to put in the file!

但是,没有提示要放入文件中的内容!

When I go to run my tests from within Eclipse it errors out saying "failed to load Application Context"....of course.

当我从Eclipse中运行我的测试时,它错误地说“无法加载应用程序上下文”....当然。

Update:

更新:

Here is test-applicationContext.xml:

这是test-applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <description>Holds application context for testing of the domain module.</description>

    <!-- Imports the uuid generator bean definitions -->
    <import resource="resources/domain-uuid.xml"/>  
</beans>

My project directory is like this:

我的项目目录是这样的:

domain/
   src/
      main/
         java/
         resources/
      test/
         java/
         resources/ (location of test-applicationContext.xml)

Just for fun I also tried to build from the mvn command line via "mvn clean test" and I got the following errors which may be my real problem:

只是为了好玩我还尝试通过“mvn clean test”从mvn命令行构建,我得到了以下错误,这可能是我真正的问题:

package org.springframework.test.context does not exist

package org.springframework.test.context.junit4 does not exist

cannot find symbol
symbol: class ContextConfiguration
@ContextConfiguration({"/resources/test-applicationContext.xml"})

cannot find symbol
symbol: class SpringJUnit4ClassRunner
@RunWith(SpringJUnit4ClassRunner.class)

2 个解决方案

#1


10  

What to put in the app context file. The way the TestContext Framework works is that it allows you to reuse app wiring in the context of your integration tests. So for the most part, there isn't anything special to tests you'd put inside your app context config files. If your controller has a service bean dependency in your app, then it will have that in your integration test too. If your DAO has a SessionFactory in your app, then same for your integration test. That way you don't have to wire all that stuff up all over again when you write integration tests. Very cool.

什么放在应用程序上下文文件中。 TestContext Framework的工作方式是允许您在集成测试的上下文中重用应用程序连接。因此,在大多数情况下,您在应用程序上下文配置文件中放置的测试没有任何特殊之处。如果您的控制器在您的应用程序中具有服务bean依赖关系,那么它也将在您的集成测试中具有该依赖关系。如果您的DAO在您的应用中有一个SessionFactory,那么您的集成测试也是如此。这样,在编写集成测试时,您不必再将所有内容连接起来。很酷。

I said for the most part above because there's at least one exception that comes to mind. Normally your app will use JNDI to locate a DataSource, but in an integration test (at least an out-of-container integration test), you won't normally have a JNDI environment available. So you should typically isolate the DataSource bean creation to a separate file, and use a JNDI version for your live app and a non-JNDI version (e.g. just create a straight BasicDataSource, say) for your integration test. Here's an example of the former:

我在上面的大部分内容中都说过,因为至少会有一个例外。通常,您的应用程序将使用JNDI来定位DataSource,但在集成测试中(至少是容器外集成测试),您通常不会有可用的JNDI环境。因此,您通常应该将DataSource bean创建隔离到单独的文件,并为您的实时应用程序使用JNDI版本,并为您的集成测试使用非JNDI版本(例如,仅创建一个直接的BasicDataSource)。这是前者的一个例子:

<jee:jndi-lookup id="dataSource" jndi-name="jdbc/myStoreDS" resource-ref="true"/>

and here's an example of the latter:

这是后者的一个例子:

<bean id="dataSource"
    class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close"
    p:driverClassName="${dataSource.driverClassName}"
    p:url="${dataSource.url}"
    p:username="${dataSource.username}"
    p:password="${dataSource.password}" />

These would go in separate files. The first might go in beans-datasource.xml for normal app use and the second in beans-datasource-it.xml for integration tests. The configuration that's common to normal app use and integration tests (i.e., the vast majority of your bean config in most cases) should be in a common config file or files.

这些将放在单独的文件中。第一个可以在beans-datasource.xml中进行正常的应用程序使用,第二个可以在beans-datasource-it.xml中进行集成测试。普通应用程序使用和集成测试(即大多数情况下绝大多数bean配置)常见的配置应该在一个或多个公共配置文件中。

Also, Spring 3 introduces a new jdbc namespace that allows you to create an embedded database, like an HSQLDB database or a Derby database, etc. It looks like this:

此外,Spring 3引入了一个新的jdbc命名空间,允许您创建嵌入式数据库,如HSQLDB数据库或Derby数据库等。它看起来像这样:

<jdbc:embedded-database id="dataSource">
    <jdbc:script location="classpath:hsql/schema.sql" />
    <jdbc:script location="classpath:hsql/test-data.sql" />
</jdbc:embedded-database>

That would replace the BasicDataSource config described above, if you want to use this.

如果你想使用它,那将取代上面描述的BasicDataSource配置。

Why the error is happening. The error you are seeing is happening because your @ContextConfiguration value is implicitly indicating that the app context file should be on the classpath. IMPORTANT: Remove the /resources piece. That is Maven innards; when it builds your JAR or WAR, it copies the contents of the resources directory into your classpath, not resources itself. That should help.

为什么会发生错误。您看到的错误正在发生,因为您的@ContextConfiguration值隐式指示应用程序上下文文件应位于类路径上。重要说明:删除/ resources piece。那是Maven的内脏;在构建JAR或WAR时,它会将资源目录的内容复制到类路径中,而不是资源本身。这应该有所帮助。

EDIT:

编辑:

To address the "no symbol found" errors, you will need to add your test dependencies to your Maven POM. This will be JUnit and the Spring Test module as well, both with <scope>test</scope>. In addition if you are using a mock framework like Mockito, you will need to add that dependency (with test scope) to your POM as well. Try that and please report back on what happens.

要解决“找不到符号”错误,您需要将测试依赖项添加到Maven POM。这也是JUnit和Spring Test模块,两者都是 test 。此外,如果您使用像Mockito这样的模拟框架,您还需要将该依赖项(带有测试范围)添加到您的POM中。试试这个,请报告发生的事情。

#2


7  

To find it directly under src/test/resources, change it to:

要直接在src / test / resources下找到它,请将其更改为:

@ContextConfiguration({"classpath:/test-applicationContext.xml"})

When you're not specifying anything, then Spring search in the same package as the test class.

当你没有指定任何东西时,Spring会在与测试类相同的包中搜索。

#1


10  

What to put in the app context file. The way the TestContext Framework works is that it allows you to reuse app wiring in the context of your integration tests. So for the most part, there isn't anything special to tests you'd put inside your app context config files. If your controller has a service bean dependency in your app, then it will have that in your integration test too. If your DAO has a SessionFactory in your app, then same for your integration test. That way you don't have to wire all that stuff up all over again when you write integration tests. Very cool.

什么放在应用程序上下文文件中。 TestContext Framework的工作方式是允许您在集成测试的上下文中重用应用程序连接。因此,在大多数情况下,您在应用程序上下文配置文件中放置的测试没有任何特殊之处。如果您的控制器在您的应用程序中具有服务bean依赖关系,那么它也将在您的集成测试中具有该依赖关系。如果您的DAO在您的应用中有一个SessionFactory,那么您的集成测试也是如此。这样,在编写集成测试时,您不必再将所有内容连接起来。很酷。

I said for the most part above because there's at least one exception that comes to mind. Normally your app will use JNDI to locate a DataSource, but in an integration test (at least an out-of-container integration test), you won't normally have a JNDI environment available. So you should typically isolate the DataSource bean creation to a separate file, and use a JNDI version for your live app and a non-JNDI version (e.g. just create a straight BasicDataSource, say) for your integration test. Here's an example of the former:

我在上面的大部分内容中都说过,因为至少会有一个例外。通常,您的应用程序将使用JNDI来定位DataSource,但在集成测试中(至少是容器外集成测试),您通常不会有可用的JNDI环境。因此,您通常应该将DataSource bean创建隔离到单独的文件,并为您的实时应用程序使用JNDI版本,并为您的集成测试使用非JNDI版本(例如,仅创建一个直接的BasicDataSource)。这是前者的一个例子:

<jee:jndi-lookup id="dataSource" jndi-name="jdbc/myStoreDS" resource-ref="true"/>

and here's an example of the latter:

这是后者的一个例子:

<bean id="dataSource"
    class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close"
    p:driverClassName="${dataSource.driverClassName}"
    p:url="${dataSource.url}"
    p:username="${dataSource.username}"
    p:password="${dataSource.password}" />

These would go in separate files. The first might go in beans-datasource.xml for normal app use and the second in beans-datasource-it.xml for integration tests. The configuration that's common to normal app use and integration tests (i.e., the vast majority of your bean config in most cases) should be in a common config file or files.

这些将放在单独的文件中。第一个可以在beans-datasource.xml中进行正常的应用程序使用,第二个可以在beans-datasource-it.xml中进行集成测试。普通应用程序使用和集成测试(即大多数情况下绝大多数bean配置)常见的配置应该在一个或多个公共配置文件中。

Also, Spring 3 introduces a new jdbc namespace that allows you to create an embedded database, like an HSQLDB database or a Derby database, etc. It looks like this:

此外,Spring 3引入了一个新的jdbc命名空间,允许您创建嵌入式数据库,如HSQLDB数据库或Derby数据库等。它看起来像这样:

<jdbc:embedded-database id="dataSource">
    <jdbc:script location="classpath:hsql/schema.sql" />
    <jdbc:script location="classpath:hsql/test-data.sql" />
</jdbc:embedded-database>

That would replace the BasicDataSource config described above, if you want to use this.

如果你想使用它,那将取代上面描述的BasicDataSource配置。

Why the error is happening. The error you are seeing is happening because your @ContextConfiguration value is implicitly indicating that the app context file should be on the classpath. IMPORTANT: Remove the /resources piece. That is Maven innards; when it builds your JAR or WAR, it copies the contents of the resources directory into your classpath, not resources itself. That should help.

为什么会发生错误。您看到的错误正在发生,因为您的@ContextConfiguration值隐式指示应用程序上下文文件应位于类路径上。重要说明:删除/ resources piece。那是Maven的内脏;在构建JAR或WAR时,它会将资源目录的内容复制到类路径中,而不是资源本身。这应该有所帮助。

EDIT:

编辑:

To address the "no symbol found" errors, you will need to add your test dependencies to your Maven POM. This will be JUnit and the Spring Test module as well, both with <scope>test</scope>. In addition if you are using a mock framework like Mockito, you will need to add that dependency (with test scope) to your POM as well. Try that and please report back on what happens.

要解决“找不到符号”错误,您需要将测试依赖项添加到Maven POM。这也是JUnit和Spring Test模块,两者都是 test 。此外,如果您使用像Mockito这样的模拟框架,您还需要将该依赖项(带有测试范围)添加到您的POM中。试试这个,请报告发生的事情。

#2


7  

To find it directly under src/test/resources, change it to:

要直接在src / test / resources下找到它,请将其更改为:

@ContextConfiguration({"classpath:/test-applicationContext.xml"})

When you're not specifying anything, then Spring search in the same package as the test class.

当你没有指定任何东西时,Spring会在与测试类相同的包中搜索。