【问题标题】:Nullpointer in simple grails controller unit test简单 grails 控制器单元测试中的空指针
【发布时间】:2014-08-28 14:57:32
【问题描述】:

我需要一些帮助来解决我在对一个非常基本的 Grails 2.4.1 控制器进行单元测试时遇到的一个奇怪问题。

给定这个控制器:

class AuthenticationEventController {
    def index() {
        // Sorry, ajax only!
        if(!request.xhr) {
            redirect(controller: "main")
            return false
        }

        render(template: "index")
        return
    }
}

还有这个测试:

@TestFor(AuthenticationEventController)
class AuthenticationEventControllerSpec extends Specification {

    void "Test that the index rejects non-ajax calls"() {
        given:
            request.isXhr = { false }

        when:
            controller.index()

        then:
            response.redirectedUrl == '/main'
    }
}

我在“controller.index()”调用中收到 NullPointerException。

java.lang.NullPointerException
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
    at org.codehaus.groovy.grails.orm.support.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:85)
    at au.com.intrinsicminds.advansys.controller.AuthenticationEventControllerSpec.Test that the index rejects non-ajax calls(AuthenticationEventControllerSpec.groovy:17)

【问题讨论】:

  • 您的测试在 grails 2.3.8 中通过(我还没有 2.4.1),所以也许它是 grails 缓存的东西 - 如果您还没有尝试过 grails clean 的话?否则,可能值得看看 Grails 2.4 中的变化
  • 为了让它在 2.4.1 中工作,我必须在测试中添加一个空的 def setup(){} 和 def cleanup() {} 方法,否则我得到方法未找到错误,也许你值得一试吗?
  • 2.4.0 和 2.4.1 都有一些严重的问题,这些问题在 2.4.2 中得到了解决。我没有机会尝试您的测试,但如果可能,我会考虑迁移到 2.4.2。
  • 你不应该需要一个空的setup()cleanup() 方法,你不应该升级到2.4.2 来测试它。 github.com/jeffbrown/xhrtest 的项目包含我粘贴到下面答案中的代码,并且该测试似乎有效。

标签: unit-testing grails


【解决方案1】:

问题很可能是您正在使用

import grails.transaction.Transactional

而不是

import org.springframework.transaction.annotation.Transactional

用于 groovy 类中的 @Transactional 注释。

为什么,对于主要区别或为什么测试对此效果不佳没有明确的答案。 此外,这通常仅在您测试一个具有 2 个以上类层的类时才会发生。

【讨论】:

  • 就我而言,我在来自 grails/src 的 spring bean 中使用 grails.transaction.Transactional。我将它切换为使用 spring 的 @Transactional,它似乎已经解决了这个问题。
  • 我在测试中也遇到了这个问题,但我的问题是我使用 grails.transaction.Transactional 时没有从 spring 上下文中获取对象。我只是为测试创建对象,因为我不需要我正在测试的部分的依赖项。使用 spring 注释将在测试时起作用,但在运行时不起作用,而 grails 注释会发生相反的情况。我不得不返回测试并允许 spring 上下文注入我正在测试的对象。
  • 这个修复也适用于我。在我使用invokeMethod 在元编程中找到NPE 之后。如果没有 NPE,grails.transaction.Transactional 一切正常
【解决方案2】:

您是否在代码中的其他任何地方使用域类?我遇到了同样的问题(TransactionTemplate#execute 引发的 NPE),解决方案是根据这个 jira 问题将@Mock 用于我的一个实体:https://jira.grails.org/browse/GRAILS-11045

【讨论】:

    【解决方案3】:

    以下内容适用于 Grails 2.4.1。

    控制器:

    // grails-app/controllers/demo/AuthenticationEventController.groovy
    package demo
    
    class AuthenticationEventController {
        def index() {
            if(!request.xhr) {
                redirect(controller: "main")
            } else {
                render(template: "index")
            }
        }
    }
    

    单元测试:

    // test/unit/demo/AuthenticationEventControllerSpec.groovy
    package demo
    
    import grails.test.mixin.TestFor
    import spock.lang.Specification
    
    @TestFor(AuthenticationEventController)
    class AuthenticationEventControllerSpec extends Specification {
    
        void "Test that the index redirects for non-ajax calls"() {
            when:
            controller.index()
    
            then:
            response.redirectedUrl == '/main'
        }
    
        void "Test that index renders template for ajax calls"() {
            given:
            request.makeAjaxRequest()
            views['/authenticationEvent/_index.gsp'] = 'my template text'
    
            when:
            controller.index()
    
            then:
            response.contentAsString == 'my template text'
        }
    }
    

    希望对你有帮助。

    【讨论】:

      【解决方案4】:

      我在尝试 Spy Transactional 服务时得到了相同的堆栈跟踪。

      我找到了对我有帮助的解决方案。所以我只是在间谍服务中初始化 transactionManager。

      参见示例:

      SomeTransactionalService sts = Spy(SomeTransactionalService)
      sts.transactionManager = transactionManager // so you need to add  init transactionManager
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-06
        • 2018-02-22
        • 2016-03-11
        相关资源
        最近更新 更多