SpringFramework和DBUnit集成测试NoSuchBeanDefinitionException Java

时间:2016-02-03 17:30:22

标签: java xml spring spring-mvc

我正在Spring控制器上编写集成测试。我有这个 NoSuchBeanDefinitionException 异常。我想我没有在xml中声明一些bean但是我找不到任何信息。

ControllerTest

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class,
        TransactionalTestExecutionListener.class, DbUnitTestExecutionListener.class })
@DatabaseSetup("login.xml")
public class LoginControllerTest2 {

    private static final String JDBC_DRIVER = "org.h2.Driver";
    private static final String JDBC_URL = "jdbc:h2:mem:login;DB_CLOSE_DELAY=-1";
    private static final String USER = "sa";
    private static final String PASS = "";
    private static final String SCHEMA_FILE = "h2.sql";
    private static final String DATASET = "login.xml";

    private MockMvc mockMvc;

    @Autowired
    private WebApplicationContext wac;

    @BeforeClass
    public static void createSchema() throws ClassNotFoundException {
        Class.forName(JDBC_DRIVER);
        try {
            Connection conn = dataSource().getConnection();
            InputStreamReader in = new InputStreamReader(LoginControllerTest2.class.getResourceAsStream(SCHEMA_FILE));
            RunScript.execute(conn, in);
        } catch (Exception e) {
            // TODO: handle exception
        }
    }

    @Before
    public void loadTestData() throws Exception {
        this.mockMvc = MockMvcBuilders.webApplicationContextSetup(this.wac).build();
        IDataSet ids = new FlatXmlDataSetBuilder().build(LoginControllerTest2.class.getResourceAsStream(DATASET));
        JdbcDatabaseTester databaseTester = new JdbcDatabaseTester(JDBC_DRIVER, JDBC_URL, USER, PASS);
        databaseTester.setSetUpOperation(org.dbunit.operation.DatabaseOperation.CLEAN_INSERT);
        databaseTester.setDataSet(ids);
        databaseTester.onSetup();
    }

    private static DataSource dataSource() {
        JdbcDataSource dataSource = new JdbcDataSource();
        dataSource.setURL(JDBC_URL);
        dataSource.setUser(USER);
        dataSource.setPassword(PASS);
        return dataSource;
    }

    @Test
    @ExpectedDatabase("login.xml")
    public void testShowForm() throws Exception {
        mockMvc.perform(get("/login")).andExpect(status().isOk()).andExpect(view().name("/login"))
                .andExpect(forwardedUrl("../../WebContent/j/login.jsp"))
                .andExpect(model().attribute("form", hasProperty("passportId", nullValue())))
                .andExpect(model().attribute("form", hasProperty("email", isEmptyOrNullString())))
                .andExpect(model().attribute("form", hasProperty("username", isEmptyOrNullString())))
                .andExpect(model().attribute("form", hasProperty("hostname", isEmptyOrNullString())))
                .andExpect(model().attribute("form", hasProperty("pass", isEmptyOrNullString())));
    }

}

堆栈跟踪

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'test.loginController.LoginControllerTest2': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.web.context.WebApplicationContext test.loginController.LoginControllerTest2.wac; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.web.context.WebApplicationContext] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:385)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:127)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:85)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:231)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:95)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:139)
    at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
    at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
    at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.web.context.WebApplicationContext test.loginController.LoginControllerTest2.wac; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.web.context.WebApplicationContext] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    ... 18 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.web.context.WebApplicationContext] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1301)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1047)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
    ... 20 more

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:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
            http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd">

    <tx:annotation-driven transaction-manager="transactionManager" />
    <context:component-scan base-package="test.loginController" />

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
        <constructor-arg>
            <bean class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
                <property name="driverClass" value="org.h2.Driver" />
                <property name="url"
                    value="jdbc:h2:mem:login;DB_CLOSE_DELAY=-1;TRACE_LEVEL_SYSTEM_OUT=2;TRACE_LEVEL_FILE=4" />
                <property name="username" value="sa" />
                <property name="password" value="" />
            </bean>
        </constructor-arg>
    </bean>

    <jdbc:initialize-database data-source="dataSource">
        <jdbc:script location="/test/loginController/h2.sql" />
    </jdbc:initialize-database>

</beans>

3 个答案:

答案 0 :(得分:0)

Spring @ContextConfiguration注释,未指定任何属性。在这种情况下,默认为GenericXmlContextLoader 尝试添加类似configuration.xml的特定文件xml:

   @ContextConfiguration("configuration.xml")
   @TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class,  TransactionalTestExecutionListener.class, DbUnitTestExecutionListener.class })
   @DatabaseSetup("login.xml")
   public class LoginControllerTest2 {

您可以使用:

  @ContextConfiguration(classes = { Name_class.class })

或者:

  @ContextConfiguration(loader=AnnotationConfigContextLoader.class)

如果您不想使用@ContextConfiguration,则只能使用@Configuration配置xml文件。

有关详细信息,请访问link

答案 1 :(得分:0)

我认为您需要将@WebAppConfiguration注释添加到您的类中,同时尝试在@ContextConfiguration注释中指定XML位置。

答案 2 :(得分:0)

我认为这个link演示了在任何地方获取应用程序上下文的最佳方法,即使在非bean类中也是如此。我发现它非常有用。希望对你来说一样。以下是它的抽象代码。

创建一个新类ApplicationContextProvider.java

    package com.myPackage.spring;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class ApplicationContextProvider implements ApplicationContextAware{

private static ApplicationContext context;

public static ApplicationContext getApplicationContext() {
    return context;
}

@Override
public void setApplicationContext(ApplicationContext ac)
        throws BeansException {
    context = ac;
   }
}

在Applkication Context.xml或您自动装配Bean的任何其他文件中添加条目

<bean id="applicationContextProvder" class="com.myPackage.spring.ApplicationContextProvider"/>

获取此类上下文

   @Autowired ApplicationContextProvider appContextProvider
     this.mockMvc = MockMvcBuilders.webApplicationContextSetup(appContextProvider.getApplicationContext()).build();

希望这有助于!!!