可以用 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: '[email protected]')
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: '[email protected]')
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())
}
}