【问题标题】:grailsApplication autowiring to spock tests are always nullgrailsApplication 自动装配到 spock 测试总是为空
【发布时间】:2015-04-13 13:24:53
【问题描述】:

Spock 测试将 null 注入到 grailsApplication,因为我尝试自动装配到 grails 服务和域对象(规范)

代码(AttackSpec.groovy)

package core

import grails.test.mixin.TestFor
import grails.test.mixin.TestMixin
import grails.test.mixin.support.GrailsUnitTestMixin
import spock.lang.Specification

/**
 * See the API for {@link grails.test.mixin.domain.DomainClassUnitTestMixin} for usage instructions
 */
@TestMixin(GrailsUnitTestMixin)
@TestFor(Attack)
class AttackSpec extends Specification {


    def grailsApplication


    def setup() {
        Attack attack = new Attack();
        println 'app '+grailsApplication.toString()
    }

    def cleanup() {

    }

    void "test something"() {
        setup:
            println 'app '+grailsApplication.toString()
    }
}

输出

log4j:WARN No appenders could be found for logger (org.codehaus.groovy.grails.commons.DefaultGrailsApplication).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
appnull
appnull
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/ops/grails-2.4.4/dist/grails-plugin-log4j-2.4.4.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/ops/grails-2.4.4/lib/org.slf4j/slf4j-simple/jars/slf4j-simple-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.GrailsSlf4jLoggerFactory]

我尝试过使用显式 @Autowired 注释和静态类型,但它总是一样的。看来我必须在某处为 grails 应用程序充气?

【问题讨论】:

  • 这是单元测试所以你不能自动装配。
  • 你是如何运行这个测试的?
  • 显示你要测试的实际功能。
  • 这是一个预备步骤,我在 resources.groovy 中有 bean,我想重复使用并坚持下去
  • 我运行测试,通过默认的 intellij 配置进行规范调试

标签: grails spock


【解决方案1】:

听起来您想要运行集成测试而不是单元测试。将您的类移动到集成测试文件夹下,您可能需要消除您的测试类注释,因为我认为这些注释仅用于单元测试。

【讨论】:

  • 这不是我想要做的,似乎答案是使用“static loadExternalBeans = true”。但我仍然无法让它工作,它不会注入 resources.groovy 中定义的 bean
【解决方案2】:

在单元测试中注入grailsApplication 有什么意义?如果你想设置一个配置,因为你的测试类:Attack 读取了 grails 应用程序的值,那么你可以模拟 grailsApplication 如下:

def 'test whatever you want to'() {
  def attack = new Attack()
  attack.grailsApplication = [config: [my: [setting: "myValue"]]] // if attack uses grailsApplication.config.my.setting internally

  when: 
  def setting = attack.getMySetting()

  then:
  setting == "myValue"
}

或者,如果您想跟踪对它的访问,您可以使用真正的 Mock。

如果您真的想使用 grails 环境进行测试,对框架上的值的访问(无论出于何种原因)是正确执行的,您应该使用集成测试。从 Spock 继承 IntegrationSpec 会将 grailsApplication 注入到您的测试中,因此您可以在 Attack 类中设置真实的东西。

【讨论】:

  • 我需要从数据库中读取攻击,我已经定义了一个 bean,它应该被持久化并读取以进行测试,现在你能解释一下第一句话吗?替代品如何更好?在 AttackSpec 之外的任何地方写入数据可能会在 db 中产生数据不一致或不需要的数据,甚至会导致我的测试失败,因为它不是独立的测试,如果有人搞砸了变量或其他一些设置测试。这样我会撕毁并拆除在非全局设置环境中清理数据库。不过我会试试你的解决方案。
  • 第一句话只是意味着,通常单元测试是一些东西,它不依赖于你想要测试的单元之外的任何东西(在 oo 语言中,这字面意思是“类”)。这是因为您希望在测试中实现隔离。由于这个原因,所有的依赖都被切断了(我这样做是为了给攻击类一个 grailsApplication 依赖的存根实现)。我不确定我是否在这里遇到问题,域类是否使用 grailsApplication?也许您必须在此处显示更多代码...
  • 嘿大卫,这只是膨胀\实例化和持久化攻击实例的另一种方式,所以我没有使用 -> attack = new Attack() ... ,而是使用预定义的 bean,grailsApplication 没有连接到 Attack 类,也没有以任何方式显式自动装配。
猜你喜欢
  • 2020-12-01
  • 2014-08-21
  • 2018-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-17
  • 2020-11-02
相关资源
最近更新 更多