【问题标题】:Spring boot, GORM, and unit testsSpring Boot、GORM 和单元测试
【发布时间】:2016-03-15 15:34:12
【问题描述】:

我有一个使用 Spring Boot 构建的项目。在这个项目中,我包含了gorm-hibernate4-spring-boot 插件,以便使用 Grails 的 GORM 对象映射糖。在运行项目时,GORM 毫无问题地做事,一切都很好。另一方面,测试是另一回事。在 Grails 项目中,我需要用 @Mock([DomainOne, DomainTwo]) 注释我的测试用例。 spring boot 的 GORM 插件工作方式不同。

关于 Spring Boot 和 GORM 的另一个问题的答案链接到 HibernateMixin 来自 grails-datastore-test-support 插件。为了使用这个 mixin,一个项目还必须有 grails @TestMixin 注释,它包含在一个工件中,它可以拉入 Grails 的其余部分。这个相同的答案还建议使用 HibernateDatastoreSpringInitializer 以在规范的 setup() 方法中初始化 GORM。不幸的是,尽管这似乎是最好的选择,但我无法让它发挥作用。

这是我的build.gradle

buildscript { // Defines dependencies and repos for the build script itself
  repositories { mavenCentral() }
  dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.7.RELEASE") }
}

apply plugin: 'groovy'
apply plugin: 'java'
apply plugin: 'application'
apply plugin: 'spring-boot'

version = 1.0
mainClassName='foo.bar.Baz'

repositories {
  mavenCentral()
  maven { url 'http://repo.spring.io/libs-milestone' }
  maven { url 'http://repo.spring.io/libs-snapshots' }
  flatDir { dirs 'lib' }
}

dependencies {
  compile("org.springframework.boot:spring-boot-starter-jdbc") {
      exclude group: "org.springframework.boot", module: "spring-boot-starter-logging"
  }
  compile("org.apache.activemq:activemq-broker") // ActiveMQ
  compile('commons-io:commons-io:2.4') // Commons IO
  compile("org.springframework.boot:spring-boot-starter-log4j") // log 4j
  compile('org.codehaus.groovy:groovy-all')
  compile('org.postgresql:postgresql:9.4-1201-jdbc41') // JDBC
  compile('log4j:log4j:1.2.17') // Default logging provider
  compile("org.grails:gorm-hibernate4-spring-boot:5.0.0.RC2") // I summon thee, gorm
  testCompile("org.spockframework:spock-core:0.7-groovy-2.0")
  testCompile("org.springframework.boot:spring-boot-starter-test")
  testCompile('com.h2database:h2:1.3.148') // h2 for GORM use during tests
}

task wrapper(type: Wrapper) {
  gradleVersion = '2.3'
}

这是我的测试用例:

class DataTypeValidatorSpec extends Specification {

    def setup() {
        // Fails with "org.hibernate.HibernateException: No Session found for current thread"
        def datastoreInitializer = new HibernateDatastoreSpringInitializer(MyDomainClass)
        def applicationContext = new GenericApplicationContext()
        def dataSource = new DriverManagerDataSource(
            "jdbc:h2:mem:grailsDb1;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_DELAY=-1",
            'sa', ''
        )
        dataSource.driverClassName = Driver.name
        applicationContext.beanFactory.registerSingleton("dataSource", dataSource)
        datastoreInitializer.configureForBeanDefinitionRegistry(applicationContext)
        applicationContext.refresh() // is this needed?
    }

    void "should do gorm stuff"() {
        given:
            MyDomainClass instance = new MyDomainClass(name: 'foo').save()
        when:
            MyDomainClass locatedInstance = MyDomainClass.findByName('foo')
        then:
            instance == locatedInstance
    }

}

我使用gradle test 运行测试。我的规范的 setup 方法中的代码是上面链接的 HibernateDatastoreSpringInitializerSpec 中使用的设置的直接翻译。

注意,这不是一个 Grails 项目,如果可能的话,我希望尽量减少与 Grails 相关的代码。提前致谢!

【问题讨论】:

  • 如果不是grails项目,请去掉grails标签
  • 我已经包含了 Grails 标签,因为它依赖于 GORM 并且可能需要一些类似的处理。我认为具有 Grails 专业知识的人最适合帮助解决这个问题。

标签: grails gradle spring-boot grails-orm spock


【解决方案1】:

如果不拖入 Grails 核心,我无法让 mocking 工作。我刚刚删除了 GORM 并使用了基于 Spring JPA / Hibernate 的实体和存储库。这些很容易与 Spock 一起使用,并为持久化、更新等提供更可见的代码流。对不起 GORM。

【讨论】:

    【解决方案2】:

    这是一个 Spring Boot 应用程序,因此请使用 Boot 集成测试注释:

    https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html

    如果你使用这些GORM会使用gorm-hibernate4-spring-boot提供的机制加载

    【讨论】:

    • Graeme,我无法使用 @IntegrationTest 注释来解决问题。这应该与上面提到的休眠配置注释结合使用吗?你能提供更多细节吗?
    • 我看到与 OP 相同的问题,有或没有 @SpringBootTest 注释
    猜你喜欢
    • 2016-05-28
    • 2015-12-20
    • 1970-01-01
    • 2017-02-08
    • 2020-08-08
    • 2020-06-25
    • 1970-01-01
    • 2017-02-01
    相关资源
    最近更新 更多