Spring4 / JUnit4嵌入式数据库无法加载,可能配置错误的项目

时间:2016-02-09 04:47:24

标签: spring-mvc junit4 hsqldb

思考我把所有东西放在一起但不是真的,所以我请求帮助。

我有一个小型的Spring 4(WebMvc)项目,它在MySQL的一个表上执行CRUD活动(在我的代码中,在Location类中)。我在Tomcat 8的Spring 4中运行正常,没有单元测试。

现在我添加单元测试但无法正确获取JUnit配置。我想我正确设置了一个嵌入式HSQL数据库,但是我的JUnit测试表明没有记录。我可以找人帮我理顺吗?

程序实际上并没有命名为“MyProgram”,路径也没有命名为“mypackagepath”,但编辑的东西缩短了。首先,这是工作程序的配置部分:

@Configuration
@ComponentScan(basePackages = "mypackagepath")
@EnableWebMvc
public class MyProgramConfiguration extends WebMvcConfigurerAdapter { ... }

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) { ... }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) { ... }
}

@Configuration
@EnableTransactionManagement
@ComponentScan({ "mypackagepath.configuration" })
@PropertySource(value = { "classpath:application.properties" })
@EnableJpaRepositories(basePackages = { "mypackagepath.dao" })
public class JpaConfiguration {

    @Autowired
    private Environment environment;

    @Bean(name="entitymanagername")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() { ... }

    @Bean
    public DataSource dataSource() { ... }

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf) { ... }
}

public class SpringMvcInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() { ... }

    @Override
    protected Class<?>[] getServletConfigClasses() { ... }

    @Override
    protected String[] getServletMappings() { ... }

}

测试代码中的类似配置器是:

@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = { "mypackagepath.configuration" }, 
        excludeFilters = @ComponentScan.Filter(value = JpaConfiguration.class, type = FilterType.ASSIGNABLE_TYPE ) )
public class TestJpaConfiguration {

    @Value("classpath:createLocationTableForTest.sql")
    private String createLocationTableScript;

    @Value("classpath:fillLocationTableForTest.sql")
    private String fillLocationTableScript;

    @Autowired
    private Environment environment;

    @Bean(name="myentitymanagername")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource(dataSource());
    em.setPersistenceUnitName("myentitymanagername");
    em.setPackagesToScan(new String[] { "mypackagepath.model" });

    JpaVendorAdapter va = new HibernateJpaVendorAdapter();
    em.setJpaVendorAdapter(va);
    em.setJpaProperties(additionalProperties());
    em.afterPropertiesSet();

    return em;
    }

    /*
     * The individual table filling scripts are defined
     * and run in the test classes. 
     */
    @Bean(destroyMethod = "shutdown")    
    public DataSource dataSource() {
        EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
        EmbeddedDatabase db = builder
            .setType(EmbeddedDatabaseType.HSQL)
            .addScript(createLocationTableScript)
            .addScript(fillLocationTableScript)
            .build();

        return db;
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
    JpaTransactionManager tm = new JpaTransactionManager();
    tm.setEntityManagerFactory( this.entityManagerFactoryBean().getObject() );

    return tm;
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
    return new PersistenceExceptionTranslationPostProcessor();
    }

    Properties additionalProperties() {
    Properties properties = new Properties();
    properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
    properties.put("hibernate.hbm2ddl.auto", environment.getRequiredProperty("hibernate.hbm2ddl.auto"));
    properties.put("jadira.usertype.autoRegisterUserTypes", environment.getRequiredProperty("jadira.usertype.autoRegisterUserTypes"));

    return properties;        
   }

}

我在main / resources和test / resources目录中都有一个application.properties文件。当然,“test”具有HSQL属性。

我认为记录没有加载(来自fillLocationTableForTest.sql文件),因为我的测试表的MySQL版本中有很多记录(如果测试配置被忽略)并且JUnit测试失败:

@Test
public final void testSummaryCountTotal() {
    Summary summary = summaryDao.getSummary();
    assertThat(summary.getCountTotal(), equalTo(12L));
}

这将返回java.lang.AssertionError:Expected&lt; 12L&gt;但是&lt; 0L&gt; ...

对于它的价值,在我的控制台中,我的JUnit运行给了我:

[main] INFO org.springframework.test.context.web.WebTestContextBootstrapper - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
[main] INFO org.springframework.test.context.web.WebTestContextBootstrapper - Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@193948d, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@1604f19, org.springframework.test.context.support.DirtiesContextTestExecutionListener@23a2f9, org.springframework.test.context.transaction.TransactionalTestExecutionListener@c0edeb, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@17e2f02]
[main] INFO org.springframework.web.context.support.GenericWebApplicationContext - Refreshing org.springframework.web.context.support.GenericWebApplicationContext@dd8682: startup date [Tue Feb 09 03:51:34 CST 2016]; root of context hierarchy
[main] INFO org.springframework.beans.factory.support.DefaultListableBeanFactory - Overriding bean definition for bean 'dataSource': replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=jpaConfiguration; factoryMethodName=dataSource; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [mypackagepath/configuration/JpaConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=testJpaConfiguration; factoryMethodName=dataSource; initMethodName=null; destroyMethodName=(inferred); defined in mypackagepath.configuration.TestJpaConfiguration]
[main] INFO org.springframework.beans.factory.support.DefaultListableBeanFactory - Overriding bean definition for bean 'exceptionTranslation': replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=jpaConfiguration; factoryMethodName=exceptionTranslation; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [mypackagepath/configuration/JpaConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=testJpaConfiguration; factoryMethodName=exceptionTranslation; initMethodName=null; destroyMethodName=(inferred); defined in mypackagepath.configuration.TestJpaConfiguration]
[main] INFO org.springframework.beans.factory.support.DefaultListableBeanFactory - Overriding bean definition for bean 'myentitymanagername': replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=jpaConfiguration; factoryMethodName=entityManagerFactory; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [mypackagepath/configuration/JpaConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=testJpaConfiguration; factoryMethodName=entityManagerFactoryBean; initMethodName=null; destroyMethodName=(inferred); defined in mypackagepath.configuration.TestJpaConfiguration]
[main] INFO org.springframework.beans.factory.support.DefaultListableBeanFactory - Overriding bean definition for bean 'transactionManager': replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=jpaConfiguration; factoryMethodName=transactionManager; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [mypackagepath/configuration/JpaConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=testJpaConfiguration; factoryMethodName=transactionManager; initMethodName=null; destroyMethodName=(inferred); defined in mypackagepath.configuration.TestJpaConfiguration]

[main] INFO org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'testJpaConfiguration' of type [class mypackagepath.configuration.TestJpaConfiguration$$EnhancerBySpringCGLIB$$d9ae76ba] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[main] INFO org.springframework.jdbc.datasource.DriverManagerDataSource - Loaded JDBC driver: org.hsqldb.jdbcDriver
[main] INFO org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean - Building JPA container EntityManagerFactory for persistence unit 'myentitymanagername'
INFO : org.hibernate.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [
    name: myentitymanagername
    ...]
INFO : org.hibernate.Version - HHH000412: Hibernate Core {4.3.6.Final}
INFO : org.hibernate.cfg.Environment - HHH000206: hibernate.properties not found
INFO : org.hibernate.cfg.Environment - HHH000021: Bytecode provider name : javassist
INFO : org.hibernate.annotations.common.Version - HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
INFO : org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.HSQLDialect
INFO : org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory - HHH000397: Using ASTQueryTranslatorFactory
INFO : org.hibernate.validator.internal.util.Version - HV000001: Hibernate Validator 5.1.3.Final
INFO : org.hibernate.type.BasicTypeRegistry - HHH000270: Type registration [java.util.Currency] overrides previous : org.hibernate.type.CurrencyType@1ffa30b
INFO : org.hibernate.tool.hbm2ddl.SchemaExport - HHH000227: Running hbm2ddl schema export
INFO : org.hibernate.tool.hbm2ddl.SchemaExport - HHH000230: Schema export complete
[main] INFO org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean - Building JPA container EntityManagerFactory for persistence unit 'myentitymanagername'
INFO : org.hibernate.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [
    name: myentitymanagername
    ...]

INFO : org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.HSQLDialect
INFO : org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory - HHH000397: Using ASTQueryTranslatorFactory
INFO : org.hibernate.type.BasicTypeRegistry - HHH000270: Type registration [java.util.Currency] overrides previous : org.hibernate.type.CurrencyType@1ffa30b
INFO : org.hibernate.tool.hbm2ddl.SchemaExport - HHH000227: Running hbm2ddl schema export
INFO : org.hibernate.tool.hbm2ddl.SchemaExport - HHH000230: Schema export complete
WARN : org.hibernate.jpa.internal.EntityManagerFactoryRegistry - HHH000436: Entity manager factory name (myentitymanagername) is already registered.  If entity manager will be clustered or passivated, specify a unique value for property 'hibernate.ejb.entitymanager_factory_name'
[main] INFO org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[//location/{id}],methods=[GET],params=[],headers=[],consumes=[],produces=[application/json],custom=[]}" onto public org.springframework.http.ResponseEntity<mypackagepath.model.Location> mypackagepath.controller.LocationController.getEdit(java.lang.Long)
[main] INFO org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[//location/{id}],methods=[PUT],params=[],headers=[],consumes=[application/json],produces=[application/json],custom=[]}" onto public org.springframework.http.ResponseEntity<mypackagepath.model.Location> mypackagepath.controller.LocationController.putEdit(mypackagepath.model.Location,java.lang.Long)
[main] INFO org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[//next/{id}/type/{type}],methods=[GET],params=[],headers=[],consumes=[],produces=[application/json],custom=[]}" onto public org.springframework.http.ResponseEntity<mypackagepath.model.Location> mypackagepath.controller.LocationController.getNextEdit(java.lang.Long,java.lang.String)
[main] INFO org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/main],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String mypackagepath.controller.MainController.getMainPage()
[main] INFO org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[//address/{address}/{key}],methods=[GET],params=[],headers=[],consumes=[],produces=[application/json],custom=[]}" onto public org.springframework.http.ResponseEntity<java.lang.String> mypackagepath.controller.ProxyAccessController.getAddress(java.lang.String,java.lang.String)
[main] INFO org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/static/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
[main] INFO org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter - Looking for @ControllerAdvice: org.springframework.web.context.support.GenericWebApplicationContext@dd8682: startup date [Tue Feb 09 03:51:34 CST 2016]; root of context hierarchy
[Thread-1] INFO org.springframework.web.context.support.GenericWebApplicationContext - Closing org.springframework.web.context.support.GenericWebApplicationContext@dd8682: startup date [Tue Feb 09 03:51:34 CST 2016]; root of context hierarchy
[Thread-1] INFO org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'myentitymanagername'

我的请求:有人可以帮我修改一个适用于Tomcat和JUnit的Spring / JUnit配置吗?

谢谢, 杰罗姆。

1 个答案:

答案 0 :(得分:0)

我解决了我的弊病,但可能不是最好的解决方案。我还在寻找更好的解决方案。

在我的TestJpaConfiguration.dataSource()中,我删除了addScript()调用:

@Bean(destroyMethod = "shutdown")    
public DataSource dataSource() {
    EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
    EmbeddedDatabase db = builder
        .setType(EmbeddedDatabaseType.HSQL)
        //.addScript(createLocationTableScript)
        //.addScript(fillLocationTableScript)
        .build();

    return db;
}

在每个测试Java文件中,我在每个setUp()/ tearDown()对中设置了一个嵌入式数据库:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { TestJpaConfiguration.class }, loader = AnnotationConfigWebContextLoader.class)
@WebAppConfiguration
public class SummaryDaoTest {

    @Value("classpath:createLocationTableForTest.sql")
    private String createLocationTableScript;

    @Value("classpath:fillLocationTableForTest.sql")
    private String fillLocationTableScript;

    @Autowired
    private EmbeddedDatabase db;

    @Autowired
    private SummaryDao summaryDao;

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
    }

    @Before
    public void setUp() throws Exception {
    db = new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.HSQL)
            .addScript(createLocationTableScript)
            .addScript(fillLocationTableScript)
            .build();
    }

    @After
    public void tearDown() throws Exception {
        db.shutdown();
    }

    // After this come the tests...

}

这适用于我 - 代码通过其JUnit测试,可部署到Tomcat并在那里正常工作。

我能否得到改善,所以我不会重复自己&#34;在每次测试中?

谢谢, 杰罗姆。