"It is not a known persistent type" when trying to save Spy object Grails 4.1.2

42 views Asked by At

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

0

There are 0 answers