grails 2.4.4集成测试不使用测试数据源

时间:2014-12-11 18:28:17

标签: grails datasource integration-testing

帮助!

我们的插件项目集成测试应该访问datasource.groovy中指定的数据库,但由于某种原因,他们会忽略它,并在内存中执行。

它是一个插件,为几个grails应用程序提供核心服务(即数据库访问),这些应用程序都是grails应用程序。

Datasource.groovy看起来像这样:

dataSource {
    pooled = true
    driverClassName = "com.mysql.jdbc.Driver"
    dialect = "org.hibernate.dialect.MySQL5InnoDBDialect"
}
environments {
    development {
        dataSource {
            dbCreate = "create-drop"
            url = "jdbc:mysql://127.0.0.1:3306/db"
            username = "someuser"
            password = "somepass"
        }
    }
    test {
        dataSource {
            dbCreate = "update"
            url = "jdbc:mysql://127.0.0.1:3306/db"
            username = "someuser"
            password = "somepass"
        }
    }
    production {
        dataSource {
        }
    }
}

测试(SiteIntegrationSpec.goovy)

import grails.test.mixin.TestFor
import grails.test.spock.IntegrationSpec

@TestFor(Site)
class SiteIntegrationSpec extends IntegrationSpec {
    static transactional = false

    def setup() {
    }

    def cleanup() {
    }

    void "test something"() {
        when:
        Site site
        site = new Site(name: "asdf", description: "asdfsd").save(failOnError: true)

        then:
        site.id == 3

        when:
        Site site2 = Site.get(1L)

        then:
        site2.name == "root"
    }
}

站点表中已存在的数据:     ID名称描述     1根root     2测试测试

第一个测试应该插入一个ID恰好为3的记录。它实际上插入ID为1,即它没有看到或击中测试数据库,它使用了一些未定义的模拟或内部数据库任何地方。

第二次测试失败,而不是检索“root”,而是检索“asdf”

我尝试过:

  1. 创建单独的数据库以进行测试。没有帮助。
  2. 在运行测试时指定-Dgrails.env = test。没帮忙
  3. 使用DB运行测试。如果无法创建池类型异常,则会正确失败。
  4. 将测试数据源密码更改为错误的密码 - 这会正确抛出异常。
  5. grails -Dgrails.env = test test-app com.me.myproject.SiteIntegrationSpec --stacktrace --verbose
  6. 所以grails连接到测试数据源,但集成测试没有使用它!

    有什么想法吗?

    编辑:网站是域对象:

    class Site {
        String name
        String description
    }
    

1 个答案:

答案 0 :(得分:2)

插件DataSource.groovy文件不包含在插件zip中,如果您以某种方式手动或以编程方式包含它们,它们将被忽略。 Config.groovyUrlMappings.groovyBootStrap.groovy也是如此。通常,当插件中有某些东西可用时,如果应用程序有一个具有相同名称和位置的文件,它会覆盖插件的文件,这样就可以防止这种情况发生。

你可以在你的插件dataSource中定义一个doWithSpring bean,它取代了基于DataSource.groovy的Grails创建的bean,它使用插件zip中存在的文件中的值,或者是位于应用程序中,如果这是有道理的。请注意,实际上有3个DataSource bean,其中两个是“真实”bean的代理,因此您需要将其定义为dataSourceUnproxied,以便其他两个代理您的并保留它们添加的行为。

解决此问题后,您需要解决的另一件事是在集成测试中使用单元测试注释。永远不要在注释或基类中使用MockTestFor或任何单元测试mix,因为它们的目的是建立一个相当真实的环境,以弥补Spring,Hibernate,已安装的插件和许多Grails功能不可用,但在集成测试中它们是可用的,单元测试的东西会踩到真实的实例。

另外 - 你为什么要使用static transactional = false?这将禁用一个重要的集成测试功能,其中所有测试方法都在一个事务中运行,该事务在测试结束时回滚通过或失败。这可确保您在测试中所做的任何事情都不会影响其他测试 - 一切都是独立的。如果禁用此功能,则需要撤消所有更改,并且很容易错过一些更改,并在测试中引入误报或更糟糕的误报。