Grails - Unit test abstract class with injected service

De openkb
Aller à : Navigation, rechercher

Sommaire

Questions

My application has a set of subclasses that all extend a certain base class.

  BaseClass.groovy   
abstract class Base {

    def beforeInsert() {
        userCreated = springSecurityService.currentUser
    }

    /* other stuff */

}
  ConcreteClass.groovy   
class Concrete extends Base {

    /* stuff, doesn t matter */

}

And I am writing a test that must instantiate several Concretes:

  RelatedServiceSpec.groovy   
def "under x circumstances, check for all instances that meet y criteria"() {

  setup: "create 3 concrete classes"
     (1..3).each { new Concrete(a:  yes ).save(validate: false) }

    /* and then the actual test ... */

}

The problem arises when I save the instances, because of that springSecurityService up in BaseClass. I can t find a way to stub it out for the unit test!

    • I can t @Mock an abstract class, which is needed to use defineBeans.
    • Base.springSecurityService raises an NPE.
    • Base.metaClass.springSecurityService and Base.metaClass.static.springSecurityService compile but don t work.
    • And apparently you can t override events in Grails, so I can t just bypass the beforeInsert, which would be fine.

Anybody know how to unit test an abstract class with an injected service?

  EDIT   

It hadn t occurred to me to inject the service into the implementation class! I ll give it a try!

Answers

What happens if you create an implementation of beforeInsert() that beforeInsert() calls and that you then override in derived classes for your tests? I haven t tried this, so I don t know if it will work, but it might be worth a shot before making Base concrete.

abstract class Base {

    def beforeInsert() {
        beforeInsertImpl()
    }

    def beforeInsertImpl() {
        userCreated = springSecurityService.currentUser
    }

    /* other stuff */
}

Within tests:

setup: "create 3 concrete classes"
     (1..3).each {
         def concrete = new Concrete(a:  yes )
         concrete.metaClass.beforeInsertImpl { /* do something with userCreated here */}
         concrete.save(validate: false)
     }

Source

License : cc by-sa 3.0

http://stackoverflow.com/questions/28819621/unit-test-abstract-class-with-injected-service

Related

Outils personnels
Espaces de noms

Variantes
Actions
Navigation
Outils