使用注入服务的单元测试抽象类

时间:2015-03-02 21:18:39

标签: unit-testing grails dependency-injection abstract-class spock

我的应用程序有一组子类,它们都扩展了某个基类。

BaseClass.groovy

abstract class Base {

    def beforeInsert() {
        userCreated = springSecurityService.currentUser
    }

    /* other stuff */

}

ConcreteClass.groovy

class Concrete extends Base {

    /* stuff, doesn't matter */

}

我正在编写一个必须实例化几个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 ... */

}

当我保存实例时出现问题,因为springSecurityService中的BaseClass向上。我无法找到一种方法将它存在单元测试中!

  • 我无法@Mock使用defineBeans所需的抽象类。
  • Base.springSecurityService提出了一个NPE。
  • Base.metaClass.springSecurityServiceBase.metaClass.static.springSecurityService已编译但无法正常工作。
  • 显然你无法覆盖Grails中的事件,所以我不能绕过beforeInsert,这没关系。

有人知道如何使用注入的服务对抽象类进行单元测试吗?

修改

我没有想到将服务注入实现类中!我试一试!

2 个答案:

答案 0 :(得分:0)

如果您创建beforeInsert() beforeInsert()调用的实现,然后在测试的派生类中重写,会发生什么?我没有试过这个,所以我不知道它是否会起作用,但在使Base具体化之前可能值得一试。

abstract class Base {

    def beforeInsert() {
        beforeInsertImpl()
    }

    def beforeInsertImpl() {
        userCreated = springSecurityService.currentUser
    }

    /* other stuff */
}

在测试中:

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)
     }

答案 1 :(得分:0)

Concrete.metaClass.getSpringSecurityService = {
    return [
        getCurrentUser: {
            return new User()
        }
    ] as SpringSecurityService
}
你可以尝试一下吗? 当然,这应该在调用new Concrete()

之前进行