简体   繁体   English

TestNG和Spring 3

[英]TestNG and Spring 3

What is the best practice way to do unit testing with Spring? 使用Spring进行单元测试的最佳实践方法是什么? I assume the combination TestNG & jmockit with Spring 3 isn't bad, so that's what I'm doing right now, but if I'm off course selecting the tools for my fresh Spring project, please tell me right away. 我假设SpringN的组合TestNG和jmockit并不坏,所以这就是我现在正在做的事情,但如果我当然没有为我的新Spring项目选择工具,请马上告诉我。 :-) :-)

Anyways, I've created an entity that I want to test, but I'm not sure how to actually run the TestNG from the Spring context. 无论如何,我已经创建了一个我想测试的实体,但我不确定如何从Spring上下文中实际运行TestNG。 I've created a simple test class 我创建了一个简单的测试类

package com.mydomain.data.entities.test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.Assert;
import org.testng.annotations.*;

@ContextConfiguration(locations={"classpath:applicationContext.xml"}) 
public class SimpleTest extends AbstractTestNGSpringContextTests {

    @Autowired
    private ApplicationContext applicationContext;

    @BeforeClass
    protected void setUp() throws Exception {
        Assert.assertNotNull(applicationContext);
    }

    @Test
    public void testNothing() {

    }

}

with applicationContext.xml importing beans for setting up the model and business layer. 使用applicationContext.xml导入bean以设置模型和业务层。 First off all, I'd like it to use the applicationContext.xml from Project/WebRoot/WEB-INF, whereas the source for this test lives in Project/src/com/mydomain/data/entities/test, but I believe that /applicationContext.xml would give me Projects/src, same as classpath: Is this correct? 首先,我希望它使用Project / WebRoot / WEB-INF中的applicationContext.xml,而此测试的源代码位于Project / src / com / mydomain / data / entities / test中,但我相信/applicationContext.xml会给我Projects / src,和classpath一样:这是正确的吗?

Furthermore, now that I'm using the model and business layers that my web application would use, I should expect it to behave similarly. 此外,既然我正在使用我的Web应用程序将使用的模型和业务层,我应该期望它的行为类似。 But, when I launch TestNG on the test, it sais: class org.hibernate.cfg.ExtendedMappings has interface org.hibernate.cfg.Mappings as super class: 但是,当我在测试中启动TestNG时,它是sais:class org.hibernate.cfg.ExtendedMappings将接口org.hibernate.cfg.Mappings作为超类:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in URL [file:/Users/niklas/Documents/Eclipse/Project/WebRoot/WEB-INF/Project-Model.xml]: Invocation of init method failed; nested exception is java.lang.IncompatibleClassChangeError: class org.hibernate.cfg.ExtendedMappings has interface org.hibernate.cfg.Mappings as super class
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1393)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:511)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:449)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:289)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:286)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:352)
    at org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors(BeanFactoryUtils.java:266)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.detectPersistenceExceptionTranslators(PersistenceExceptionTranslationInterceptor.java:121)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.<init>(PersistenceExceptionTranslationInterceptor.java:77)
    at org.springframework.dao.annotation.PersistenceExceptionTranslationAdvisor.<init>(PersistenceExceptionTranslationAdvisor.java:70)
    at org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor.setBeanFactory(PersistenceExceptionTranslationPostProcessor.java:99)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1414)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1381)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:511)
    ... 38 more
Caused by: java.lang.IncompatibleClassChangeError: class org.hibernate.cfg.ExtendedMappings has interface org.hibernate.cfg.Mappings as super class
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:700)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:56)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:319)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:330)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:254)
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:399)
    at org.hibernate.cfg.AnnotationConfiguration.createExtendedMappings(AnnotationConfiguration.java:187)
    at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:277)
    at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1162)
    at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:667)
    at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:211)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1452)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1390)
    ... 53 more

What is this and why am I getting this? 这是什么,为什么我得到这个? Any clues? 有线索吗?

My sessionFactory looks like this 我的sessionFactory看起来像这样

  <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="annotatedClasses">
      <list>
       <!-- Entity classes from package com.mydomain.data.entities -->
      </list>
    </property>
    <property name="hibernateProperties">
      <props>
        <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
        <prop key="hibernate.show_sql">false</prop>
      </props>
    </property>
  </bean>

Your test ckass needs to extend AbstractTestNGSpringContextTests . 您的测试ckass需要扩展AbstractTestNGSpringContextTests Or if your code is testing database acces another useful class to extend is AbstractTransactionalTestNGSpringContextTests . 或者,如果您的代码正在测试数据库访问,则另一个有用的扩展类是AbstractTransactionalTestNGSpringContextTests

Now the problem doesn't seem to be related to any of Spring or TestNG. 现在问题似乎与Spring或TestNG中的任何一个都没有关系。 The key part is: 关键部分是:

 java.lang.IncompatibleClassChangeError: class org.hibernate.cfg.ExtendedMappings has interface org.hibernate.cfg.Mappings as super class

Are you sure your CLASSPATH is OK? 你确定你的CLASSPATH没问题吗? Ie you have compatible version of Hibernate modules and no repetitions there? 即你有兼容的Hibernate模块版本,没有重复?

What if you create a simple TestNG test that does the following: 如果您创建一个执行以下操作的简单TestNG测试,该怎么办?

Class.forName("org.hibernate.cfg.ExtendedMappings");

?

Consult the chapter on TestNG in the Spring documentation: 请参阅Spring文档中有关TestNG的章节:

For me this problem was caused because I had different hibernate versions included myself, not because of a third party including them. 对我来说这个问题是因为我自己包含了不同的hibernate版本,而不是因为包含它们的第三方。 A sweep of your project/poms to make sure you youserlf are only using one hibernate version is worthwhile. 扫描你的项目/ poms以确保你的服务器只使用一个休眠版本是值得的。

You might want to try hibernate-annotations-3.5.0-Beta-1 as this aligns with hibernate-core-3.5.0-Beta-1. 您可能想尝试hibernate-annotations-3.5.0-Beta-1,因为这与hibernate-core-3.5.0-Beta-1一致。

I still get the java.lang.IncompatibleClassChangeError sometimes, as I'm trying to use hibernate search which is using the "old" annotations. 有时我仍然会得到java.lang.IncompatibleClassChangeError,因为我正在尝试使用使用“旧”注释的hibernate搜索。

Also, not sure if you are running JBoss, but if you are you'll get this error with core 3.5.0. 此外,不确定您是否正在运行JBoss,但如果您是这样,您将在核心3.5.0上遇到此错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM