帮助!
我们的插件项目集成测试应该访问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”
我尝试过:
所以grails连接到测试数据源,但集成测试没有使用它!
有什么想法吗?
编辑:网站是域对象:
class Site {
String name
String description
}
答案 0 :(得分:2)
插件DataSource.groovy
文件不包含在插件zip中,如果您以某种方式手动或以编程方式包含它们,它们将被忽略。 Config.groovy
,UrlMappings.groovy
和BootStrap.groovy
也是如此。通常,当插件中有某些东西可用时,如果应用程序有一个具有相同名称和位置的文件,它会覆盖插件的文件,这样就可以防止这种情况发生。
你可以在你的插件dataSource
中定义一个doWithSpring
bean,它取代了基于DataSource.groovy
的Grails创建的bean,它使用插件zip中存在的文件中的值,或者是位于应用程序中,如果这是有道理的。请注意,实际上有3个DataSource bean,其中两个是“真实”bean的代理,因此您需要将其定义为dataSourceUnproxied
,以便其他两个代理您的并保留它们添加的行为。
解决此问题后,您需要解决的另一件事是在集成测试中使用单元测试注释。永远不要在注释或基类中使用Mock
,TestFor
或任何单元测试mix,因为它们的目的是建立一个相当真实的环境,以弥补Spring,Hibernate,已安装的插件和许多Grails功能不可用,但在集成测试中它们是可用的,单元测试的东西会踩到真实的实例。
另外 - 你为什么要使用static transactional = false
?这将禁用一个重要的集成测试功能,其中所有测试方法都在一个事务中运行,该事务在测试结束时回滚通过或失败。这可确保您在测试中所做的任何事情都不会影响其他测试 - 一切都是独立的。如果禁用此功能,则需要撤消所有更改,并且很容易错过一些更改,并在测试中引入误报或更糟糕的误报。