如何测试具有Basecontroller的@Mixin的控制器

时间:2013-06-08 01:31:50

标签: grails spock

我已经创建了一个BaseController,我将其混合到其他控制器中。

示例:

class BaseController () {
  def somemethod () {
    return "some method"
  }
}

@Mixin(BaseController)

class MyController {
   def getsomething() {
     def test = somemethod()
     return test
   }
}

我正在尝试为MyController编写一个测试用例但是,它失败了,因为找不到somemethod

我的测试目前看起来像这样

@TestFor(MyController)
class MyControllerSpec extends Specification {
  def "test getsomething" () {
    when:
      def m = controller.getsomething()
    then:
      response.contentAsString == "some method"
  }
}

但我一直收到这样的错误:

No signature of method: somemethod() is applicable for argument types: () values: []

问题

如何为MyController编写spock测试,以便找到somemethod

3 个答案:

答案 0 :(得分:4)

@TestMixin(BaseController)的Spock测试中使用MyController是否正常工作? 答: - 不,不是必需的。

<强>更新
MyController需要进行少量修改。使用render代替return。这是详细信息:

class BaseController {
    def someMethod() { 
        "Some Method"
    }
}

import grails.util.Mixin
//Remember to use Grails @Mixin instead of Groovy @Mixin
@Mixin(BaseController)
class MyController {
    def getSomething() {
        def test = someMethod()
        render test
    }
}

//Unit Test
@TestFor(MyController)
class MyControllerUnitSpec extends Specification {
    void "test get something"() {
        when:
            controller.getSomething()
        then:
            response.contentAsString == "Some Method"
    }
}

//Controller Integration Test
import grails.plugin.spock.ControllerSpec
class MyControllerIntSpec extends ControllerSpec {
    void "test get something integration"() {
        when:
            controller.getSomething()
        then:
            controller.response.contentAsString == "Some Method"
    }
}

备注: -
我在测试时发现了一些困难,如下所示: -

  • 上述测试在初始运行时通过。但是,当我将render更改为return只是为了看到我的测试失败时,由于我在@Mixin中使用的Grails MyControllerwithFormat的两个版本,我收到了编译错误1}})。有时我认为它不能很好地发挥作用。将mixin更改为Groovy @Mixin一切都很顺利。我不喜欢那样。我不得不坚持Grails @Mixin。显然和令人惊讶的是,做grails clean && grails compile根除了这个问题。我能够正确使用Grails @Mixin。我仍在关注这种差异。

  • 如果上述问题持续存在,我会考虑在单元测试中的setup()方法中添加运行时mixin。

def setup(){
    //I would not like to do the same in Integration test
    //Integration test should do it for me atleast. 
    MyController.mixin BaseController
}
  • 我在集成测试中使用了ControllerSpec而不是IntegrationSpec。似乎注入和约定在控制器的ControllerSpec中得到了更好的维护。如果你看到,我在任何地方都没有在int测试中实例化MyContoller

  • 我没有在正常的Junit单元和集成测试中测试它们,它们也应该很好。

答案 1 :(得分:3)

我强烈建议不要在Grails中使用mixins 。它会在测试中产生错误的行为。你还需要一个额外的代码来应用这些mixin进行测试,这很糟糕。

有关详细信息,请阅读此重播:http://grails.1312388.n4.nabble.com/grails-2-2-2-upgrade-from-2-2-0-breaks-mixin-on-controller-tp4645461p4645466.html,它适用于一般Grails中的mixins,或者查看此问题的评论中报告的许多问题:http://jira.grails.org/browse/GRAILS-8652(类在单元期间丢失其mixins测试)。

答案 2 :(得分:1)

根据此主题中的答案,http://grails.1312388.n4.nabble.com/Testing-a-controller-that-has-a-Mixin-td4645595.html

我最终使用了,

void setup() {
    MyController.mixin(BaseController)
}