可以用 Domain Unit Test 来模拟领域类的 save()、查询等功能
示例代码:
package demo
class Person {
String firstName
String lastName
}
/// src/test/groovy/demo/PersonSpec.groovy
package demo
import grails.testing.gorm.DomainUnitTest
import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Stepwise
@Stepwise
class PersonSpec extends Specification implements DomainUnitTest<Person> {
@Shared int id
void "test basic persistence mocking"() {
setup:
new Person(firstName: 'Robert', lastName: 'Fripp').save()
new Person(firstName: 'Adrian', lastName: 'Belew').save()
expect:
Person.count() == 2
}
void "test domain instance"() {
setup:
id = System.identityHashCode(domain)
expect:
domain != null
domain.hashCode() == id
when:
domain.firstName = 'Robert'
then:
domain.firstName == 'Robert'
}
void "test we get a new domain"() {
expect:
domain != null
domain.firstName == null
System.identityHashCode(domain) != id
}
}
如果要对多个领域类测试,可以使用 grails.testing.gorm.DataTest
traits,注意,需要显示调用 mockDomain or mockDomains
方法,设置要模拟的Domain类,如下:
package demo
import grails.testing.gorm.DataTest
import spock.lang.Specification
class DataTestTraitSpec extends Specification implements DataTest {
void setupSpec() {
mockDomain Person
// for multiple domains, call mockDomains...
// mockDomains Person, Address, Company
}
void "test basic persistence mocking"() {
setup:
new Person(firstName: 'Robert', lastName: 'Fripp').save()
new Person(firstName: 'Adrian', lastName: 'Belew').save()
expect:
Person.count() == 2
}
}
也可以通过重载Class[] getDomainClassesToMock() method
来指定 mock domain classes:
package demo
import grails.testing.gorm.DataTest
import spock.lang.Specification
class GetDomainClassesToMockMethodSpec extends Specification implements DataTest {
Class[] getDomainClassesToMock() {
Person
}
void "test basic persistence mocking"() {
setup:
new Person(firstName: 'Robert', lastName: 'Fripp').save()
new Person(firstName: 'Adrian', lastName: 'Belew').save()
expect:
Person.count() == 2
}
}
可以用 HibernateSpec 来测试 domain class 的 constraints 是否满足设计要求
如唯一约束、格式约束、非空约束是否满足设计要求;还可以验证错误消息是否提示正确。
示例代码如下,注意继承了 HibernateSpec 而不是 DomainUnitTest:
import grails.test.hibernate.HibernateSpec
@SuppressWarnings('MethodName')
class HotelEmailUniqueConstraintSpec extends HibernateSpec {
List<Class> getDomainClasses() { [Hotel] }
def "hotel's email unique constraint"() {
when: 'You instantiate a hotel with name and an email address which has been never used before'
def hotel = new Hotel(name: 'Hotel Transilvania', email: 'info@hoteltransilvania.com')
then: 'hotel is valid instance'
hotel.validate()
and: 'we can save it, and we get back a not null GORM Entity'
hotel.save()
and: 'there is one additional Hotel'
Hotel.count() == old(Hotel.count()) + 1
when: 'instanting a different hotel with the same email address'
def hilton = new Hotel(name: 'Hilton Hotel', email: 'info@hoteltransilvania.com')
then: 'the hotel instance is not valid'
!hilton.validate(['email'])
and: 'unique error code is populated'
hilton.errors['email']?.code == 'unique'
and: 'trying to save fails too'
!hilton.save()
and: 'no hotel has been added'
Hotel.count() == old(Hotel.count())
}
}