代码之家  ›  专栏  ›  技术社区  ›  Thom

添加模拟中断数据库测试

  •  1
  • Thom  · 技术社区  · 6 年前

    我搜遍了所有我能想到的东西,但都没有用。我用弹簧4.3.1跑步。

    我已经继承了一个应用程序,并且正在努力加强单元测试以使其变得有用。

    作为其中的一部分,我在单元测试中添加了以下行:

    Mockito.when(udfConfigurationRepository.save(any(UDFConfiguration.class))).thenAnswer(parm -> parm.getArguments()[0]);
    

    单元测试运行良好。然后,我运行了应用程序的生成,得到以下错误:

    java.lang.IllegalStateException: Failed to load ApplicationContext
    
        at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
        at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
        at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
        at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
        at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
        at org.springframework.test.context.testng.AbstractTestNGSpringContextTests.springTestContextPrepareTestInstance(AbstractTestNGSpringContextTests.java:149)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
        at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:564)
        at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
        at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138)
        at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:175)
        at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:107)
        at org.testng.TestRunner.privateRun(TestRunner.java:767)
        at org.testng.TestRunner.run(TestRunner.java:617)
        at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
        at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
        at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
        at org.testng.SuiteRunner.run(SuiteRunner.java:240)
        at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
        at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
        at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
        at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
        at org.testng.TestNG.run(TestNG.java:1057)
        at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
        at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [applicationContext-dao-test.xml]: Invocation of init method failed; nested exception is java.lang.RuntimeException: error trying to scan <jar-file>: file:/C:/casenet/Sources/provider-portal/portal-server/target/test-classes
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
        at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1076)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:851)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
        at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:128)
        at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
        at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:108)
        at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:251)
        at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
        at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
        ... 28 more
    Caused by: java.lang.RuntimeException: error trying to scan <jar-file>: file:/C:/casenet/Sources/provider-portal/portal-server/target/test-classes
        at org.hibernate.ejb.Ejb3Configuration.scanForClasses(Ejb3Configuration.java:855)
        at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:597)
        at org.springframework.orm.jpa.vendor.SpringHibernateEjbPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateEjbPersistenceProvider.java:50)
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:338)
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:373)
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:362)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
        ... 43 more
    Caused by: java.lang.RuntimeException: Error while reading file:/C:/casenet/Sources/provider-portal/portal-server/target/test-classes
        at org.hibernate.ejb.packaging.NativeScanner.getClassesInJar(NativeScanner.java:131)
        at org.hibernate.ejb.Ejb3Configuration.addScannedEntries(Ejb3Configuration.java:485)
        at org.hibernate.ejb.Ejb3Configuration.scanForClasses(Ejb3Configuration.java:852)
        ... 50 more
    Caused by: java.io.IOException: invalid constant type: 18
        at javassist.bytecode.ConstPool.readOne(ConstPool.java:1113)
        at javassist.bytecode.ConstPool.read(ConstPool.java:1056)
        at javassist.bytecode.ConstPool.<init>(ConstPool.java:150)
        at javassist.bytecode.ClassFile.read(ClassFile.java:765)
        at javassist.bytecode.ClassFile.<init>(ClassFile.java:109)
        at org.hibernate.ejb.packaging.AbstractJarVisitor.checkAnnotationMatching(AbstractJarVisitor.java:246)
        at org.hibernate.ejb.packaging.AbstractJarVisitor.executeJavaElementFilter(AbstractJarVisitor.java:212)
        at org.hibernate.ejb.packaging.AbstractJarVisitor.addElement(AbstractJarVisitor.java:173)
        at org.hibernate.ejb.packaging.ExplodedJarVisitor.getClassNamesInTree(ExplodedJarVisitor.java:126)
        at org.hibernate.ejb.packaging.ExplodedJarVisitor.getClassNamesInTree(ExplodedJarVisitor.java:134)
        at org.hibernate.ejb.packaging.ExplodedJarVisitor.getClassNamesInTree(ExplodedJarVisitor.java:134)
        at org.hibernate.ejb.packaging.ExplodedJarVisitor.getClassNamesInTree(ExplodedJarVisitor.java:134)
        at org.hibernate.ejb.packaging.ExplodedJarVisitor.getClassNamesInTree(ExplodedJarVisitor.java:134)
        at org.hibernate.ejb.packaging.ExplodedJarVisitor.getClassNamesInTree(ExplodedJarVisitor.java:134)
        at org.hibernate.ejb.packaging.ExplodedJarVisitor.doProcessElements(ExplodedJarVisitor.java:92)
        at org.hibernate.ejb.packaging.AbstractJarVisitor.getMatchingEntries(AbstractJarVisitor.java:149)
        at org.hibernate.ejb.packaging.NativeScanner.getClassesInJar(NativeScanner.java:128)
        ... 52 more
    

    在通过spring实际测试存储库的所有测试中,都会再次出现此错误。我能想到的唯一一件事是,通过嘲弄这份回购协议,它已经把春天的工作弄糟了。

    所有数据库测试都继承自这个基类。

    @ContextConfiguration(locations = { "/applicationContext-dao-test.xml" })
    @Transactional
    @TestExecutionListeners( { TransactionalTestExecutionListener.class })
    public class BaseRepositoryTest extends AbstractTestNGSpringContextTests{
        public BaseRepositoryTest(){ super(); }
    }
    

    下面是applicationcontext-dao-test.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"
           xmlns:jpa = "http://www.springframework.org/schema/data/jpa" xmlns:p = "http://www.springframework.org/schema/p"
           xmlns:tx = "http://www.springframework.org/schema/tx"
           xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
    
        <context:component-scan  base-package="com.casenet.portals.repository" />
        <context:component-scan  base-package="com.casenet.portals.services" />
    
        <jpa:repositories base-package = "com.casenet.portals.repository"/>
    
        <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >
            <property name="dataSource" ref="portalDataSource"/>
            <property name="packagesToScan">
                <list>
                    <value>com.casenet.portals.repository</value>
                    <value>com.casenet.portals.domain</value>
                </list>
            </property>
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                    <prop key="hibernate.show_sql">${hibernate.show_sql:false}</prop>
                    <prop key="hibernate.format_sql">${hibernate.format_sql:false}</prop>
                </props>
            </property>
        </bean>
    
        <bean id="entityManagerFactory"
              class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
            <property name="persistenceXmlLocation" value="classpath*:META-INF/persistence-test.xml" />
            <property name="persistenceUnitName" value="casenet" />
            <property name="jpaVendorAdapter">
                <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                    <property name="showSql" value="false" />
                </bean>
            </property>
        </bean>
    
        <bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
    
        <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
            <property name="entityManagerFactory" ref="entityManagerFactory" />
            <property name="dataSource" ref="portalDataSource"/>
            <property name="jpaDialect" ref="jpaDialect" />
        </bean>
    
    
        <bean id="portalDataSource"
              class="org.springframework.jdbc.datasource.DriverManagerDataSource"
              p:driverClassName="org.hsqldb.jdbcDriver"
              p:url="jdbc:hsqldb:mem:casenetApplication;sql.enforce_strict_size=true"
              p:username="sa"
              p:password="" />
    
        <tx:annotation-driven transaction-manager="transactionManager" />
    </beans>
    

    所有这些测试现在都失败了,唯一的改变是一行代码模拟了我的存储库。

    我有一种感觉,这与上下文有关,我可以用这种方法解决它,但似乎找不到合适的方法来分离它们。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Thom    6 年前

    如评论所示,答案在于 Reflections - Java 8 - invalid constant type .

    事实证明,常量:18是指使用Java 8风格的lambdas,而不是在Java 8下编译的库。

    所以为了解决这个问题,我必须编写更多的代码如下:

    Mockito.when(udfConfigurationRepository.save(any(UDFConfiguration.class))).thenAnswer(new Answer<UDFConfiguration>() {
            @Override
            public UDFConfiguration answer(InvocationOnMock invocationOnMock) throws Throwable {
                UDFConfiguration config = (UDFConfiguration) invocationOnMock.getArguments()[0];
                return config;
            }
        });
    

    这样做修复了这个单元测试和所有其他的单元测试。