Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 带有注入服务的单元测试抽象类_Unit Testing_Grails_Dependency Injection_Abstract Class_Spock - Fatal编程技术网

Unit testing 带有注入服务的单元测试抽象类

Unit testing 带有注入服务的单元测试抽象类,unit-testing,grails,dependency-injection,abstract-class,spock,Unit Testing,Grails,Dependency Injection,Abstract Class,Spock,我的应用程序有一组子类,它们都扩展了某个基类 基类.groovy abstract class Base { def beforeInsert() { userCreated = springSecurityService.currentUser } /* other stuff */ } class Concrete extends Base { /* stuff, doesn't matter */ } def "under x

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

基类.groovy

abstract class Base {

    def beforeInsert() {
        userCreated = springSecurityService.currentUser
    }

    /* other stuff */

}
class Concrete extends Base {

    /* stuff, doesn't matter */

}
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 ... */

}
ConcreteClass.groovy

abstract class Base {

    def beforeInsert() {
        userCreated = springSecurityService.currentUser
    }

    /* other stuff */

}
class Concrete extends Base {

    /* stuff, doesn't matter */

}
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 ... */

}
我正在编写一个测试,它必须实例化几个具体实例:

相关服务规范groovy

abstract class Base {

    def beforeInsert() {
        userCreated = springSecurityService.currentUser
    }

    /* other stuff */

}
class Concrete extends Base {

    /* stuff, doesn't matter */

}
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 ... */

}
当我保存实例时会出现问题,因为
BaseClass
中出现了
springSecurityService
。我找不到在单元测试中删除它的方法

  • 我不能
    @Mock
    使用
    defineBeans
    所需的抽象类
  • Base.springSecurityService
    引发NPE
  • Base.metaClass.springSecurityService
    Base.metaClass.static.springSecurityService
    编译但不工作
  • 显然,您无法覆盖Grails中的事件,因此我不能在插入之前跳过
    ,这很好
有人知道如何使用注入服务对抽象类进行单元测试吗

编辑


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

如果您创建了一个
beforeinstert()
的实现,该实现调用了
beforeinstert()
并在测试的派生类中重写,会发生什么?我还没有尝试过这个,所以我不知道它是否有效,但在使
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)
     }
你能试试这个吗?
当然,这应该在调用new Concrete()之前进行。

如果根本没有会话/springSecurity,如何处理用户创建的问题?e、 g.创建这些对象的批处理作业或在引导中?该问题尚未出现。它们当前仅由用户直接创建,或作为用户另一个操作的副作用创建。应该如何处理,这是如何处理这种情况的线索吗?我只是想知道或提出这一点。如果它们可以为null,只需使用springSecurityService?.currentUser,或者如果有默认用户(系统、管理员等),只需在那里分配此用户。不管怎样,原始问题仍然有效。仔细考虑后,我认为这不是可选字段,也没有默认用户。我不喜欢为了通过测试而修改代码的想法。也许我应该把
Base
具体化……我没有想到将服务注入到实现类中!我要试试看!这是个不错的主意,如果将服务注入派生类不起作用,可能必须尝试一下。