I cannot save to database object which is spying on other object. That makes testing more difficult.
Is there any workaround to this problem or do you know if it is intentioned? I am not sure if this is an bug or not.
My testing code
// grails-app/domain/Person.groovy
class Person{
String name = ""
String surname = ""
static mapping = {
id generator: 'identity'
}
}
// src/test/groovy/PersonSpec.groovy
import grails.testing.gorm.DataTest
import spock.lang.Specification
class PersonSpec extends Specification implements DataTest {
def setupSpec() {
mockDomain Person
}
def "persist person"(){
setup:
Person person = new Person()
when:
person.save()
then:
true
}
def "persist spy"(){
setup:
Person person = Spy()
when:
person.save()
then:
true
}
}
// build.gradle
buildscript {
repositories {
maven { url "https://repo.grails.org/grails/core" }
}
dependencies {
classpath "org.grails:grails-gradle-plugin:$grailsVersion"
}
}
repositories {
maven { url "https://repo.grails.org/grails/core" }
}
version "0.1"
group "testapp"
apply plugin:"org.grails.grails-web"
dependencies {
compile "org.grails.plugins:hibernate5"
testCompile "org.grails:grails-gorm-testing-support"
}
# gradle.properties
grailsVersion=4.1.2
First test passes, second not.
Error message:
Object [Person : (unsaved)] cannot be persisted. It is not a known persistent type.
org.grails.datastore.mapping.engine.NonPersistentTypeException: Object [Person : (unsaved)] cannot be persisted. It is not a known persistent type.
at org.grails.datastore.mapping.core.AbstractSession.persist(AbstractSession.java:591)
at org.grails.datastore.gorm.GormInstanceApi.doSave(GormInstanceApi.groovy:365)
at org.grails.datastore.gorm.GormInstanceApi.save_closure5(GormInstanceApi.groovy:180)
at groovy.lang.Closure.call(Closure.java:405)
at org.grails.datastore.mapping.core.DatastoreUtils.execute(DatastoreUtils.java:319)
at org.grails.datastore.gorm.AbstractDatastoreApi.execute(AbstractDatastoreApi.groovy:40)
at org.grails.datastore.gorm.GormInstanceApi.save(GormInstanceApi.groovy:179)
at org.grails.datastore.gorm.GormInstanceApi.save(GormInstanceApi.groovy:119)
at org.grails.datastore.gorm.GormEntity$Trait$Helper.save(GormEntity.groovy:107)
at org.spockframework.mock.runtime.ByteBuddyMethodInvoker.respond(ByteBuddyMethodInvoker.java:20)
at org.spockframework.mock.runtime.MockInvocation.callRealMethod(MockInvocation.java:59)
at org.spockframework.mock.CallRealMethodResponse.respond(CallRealMethodResponse.java:30)
at org.spockframework.mock.runtime.MockController.handle(MockController.java:50)
at org.spockframework.mock.runtime.JavaMockInterceptor.intercept(JavaMockInterceptor.java:72)
at org.spockframework.mock.runtime.ByteBuddyInterceptorAdapter.interceptNonAbstract(ByteBuddyInterceptorAdapter.java:35)
at PersonSpec.persist spy(PersonSpec.groovy:23)
Isn't that the spy object should use original object method when there is no mocks? Then above should work. This is simplified version; in my current project I generate Person object with some data to each test and then use it to create Spy with personObject = Spy(personObject).
Gradle version 5.6.4