Overriding dateCreated for testing in Grails

后端 未结 10 1441
日久生厌
日久生厌 2021-02-12 12:27

Is there any way I can override the value of dateCreated field in my domain class without turning off auto timestamping?

I need to test controller and I ha

10条回答
  •  猫巷女王i
    2021-02-12 13:23

    Getting a hold of the ClosureEventListener allows you to temporarily disable grails timestamping.

    import org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes
    import org.codehaus.groovy.grails.commons.spring.GrailsWebApplicationContext
    import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration
    import org.codehaus.groovy.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor
    import org.codehaus.groovy.grails.orm.hibernate.support.ClosureEventListener
    
    class FluxCapacitorController {
    
        def backToFuture = {
            changeTimestamping(new Message(), false)
            Message m = new Message()
            m.dateCreated = new Date("11/5/1955")
            m.save(failOnError: true)
            changeTimestamping(new Message(), true)
        }
    
        private void changeTimestamping(Object domainObjectInstance, boolean shouldTimestamp) {
            GrailsWebApplicationContext applicationContext = servletContext.getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT)
            GrailsAnnotationConfiguration configuration = applicationContext.getBean("&sessionFactory").configuration
            ClosureEventTriggeringInterceptor interceptor = configuration.getEventListeners().saveOrUpdateEventListeners[0]
            ClosureEventListener listener = interceptor.findEventListener(domainObjectInstance)
            listener.shouldTimestamp = shouldTimestamp
        }
    }
    

    There may be an easier way to get the applicationContext or Hibernate configuration but that worked for me when running the app. It does not work in an integration test, if anyone figures out how to do that let me know.

    Update

    For Grails 2 use eventTriggeringInterceptor

    private void changeTimestamping(Object domainObjectInstance, boolean shouldTimestamp) {
        GrailsWebApplicationContext applicationContext = servletContext.getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT)
        ClosureEventTriggeringInterceptor closureInterceptor = applicationContext.getBean("eventTriggeringInterceptor")
        HibernateDatastore datastore = closureInterceptor.datastores.values().iterator().next()
        EventTriggeringInterceptor interceptor = datastore.getEventTriggeringInterceptor()
    
        ClosureEventListener listener = interceptor.findEventListener(domainObjectInstance)
        listener.shouldTimestamp = shouldTimestamp
    }
    

提交回复
热议问题