我正在从grails 1.3.6迁移到2.2.4。我目前在集成测试期间使用withNewSession时遇到问题。我已经建立了一个演示项目来更清楚地表示问题。代码如下:
class DomainA {
String id
String domainB
String description
static constraints =
{
id unique: true, nullable:false
domainB (nullable: false, blank:false,
validator:{val, obj ->
if(val != null)
{
DomainA.withNewSession{session ->
def result = DomainB.findByDescription(val)
if(result == null)
{
return 'foreignkey'
}
}
}
})
}
static mapping =
{
table 'DOMAIN_A'
id column:'id', type: 'string', generator: 'assigned'
version false
domainB column:'DOMAIN_B'
}
}
class DomainB {
String id
String description
static constraints =
{
id unique: true, nullable:false
description nullable:false
}
static mapping =
{
table 'DOMAIN_B'
id column:'id', type: 'string', generator: 'assigned'
version false
}
}
和整合测试
import static org.junit.Assert.*
import org.junit.*
class WithNewSessionTestTests extends GroovyTestCase{
@Before
void setUp() {
DomainB b = new DomainB(description:"BEE")
b.id = "B"
b.save(flush:true, failOnError:true)
DomainA a = new DomainA(domainB:"BEE", description:"EHH")
a.id = "A"
a.save(flush:true, failOnError:true)
}
@Test
void testSomething() {
assertTrue true
}
}
a
尝试保存时测试失败。返回的错误代码是“foreignkey”,这是DomainA
无法找到DomainB
实例时返回的内容。调试还向我显示DomainB.findByDescription(val)
的结果值为null
。关于如何解决这个问题的任何想法?我希望我的测试继续是事务性的以避免
如果我从验证中删除withNewSession
或者将测试设置为static transactional = false
,则此测试将成功。关于如何保留withNewSession调用和测试的事务性质的任何想法?
版本:Grails 2.2.4,Oracle 10 +,Java 7.0.21,groovy 2.0.7
答案 0 :(得分:0)
更改
class DomainA {
String id
String domainB
String description
----- rest of the code
}
到
class DomainA {
String id
DomainB domainB
String description
}
在集成测试中
import static org.junit.Assert.*
import org.junit.*
class WithNewSessionTestTests extends GroovyTestCase{
@Before
void setUp() {
DomainB b = new DomainB(description:"BEE")
b.id = "B"
b.save(flush:true, failOnError:true)
DomainA a = new DomainA(domainB:b, description:"EHH")
a.id = "A"
a.save(flush:true, failOnError:true)
}
@Test
void testSomething() {
assertTrue true
}
}
这应该有用。
修改强>
默认情况下,集成测试在数据库事务中运行 在每次测试结束时回滚。这意味着保存了数据 在测试期间没有持久化到数据库。添加交易 测试类的属性以检查事务行为:
class MyServiceTests extends GroovyTestCase {
static transactional = false
void testMyTransactionalServiceMethod() {
…
} }
请务必从非事务性测试中删除任何持久数据, 例如在tearDown方法中,所以这些测试不会干扰 标准的事务测试需要一个干净的数据库。
如果没有static transactional = false
,则测试必须持久存储到db,并且在集成测试中,数据将被回滚而不会持久保存到数据库中。