为什么这个方法返回null,即使底层控制器使用Spock的Mock()模拟? [英] Why is this method returning null even though the underlying controller is mocked using Spocks' Mock()?

查看:158
本文介绍了为什么这个方法返回null,即使底层控制器使用Spock的Mock()模拟?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  import grails.plugin.spock。* 
$ b $ class EventControllerSpec extends ControllerSpec {

def从事件创建面包屑 (){
given:我有一个命名事件
def eventController = Mock(EventController)
def event = Mock(Event)
event.title>> 'Sprock和Crew的Space-Journey'
event.title =='Sprock和Crew的Space-Journey'

当:我从它创建一个面包屑
def eventCrumb = eventController.createCrumb(Event,show,1,event.title)

/ *
private Map createCrumb(String controllerName,String actionName,String id ,msg){
msg =(msg?msg:cr.breadcrumb。$ {controllerName}。$ {actionName})
['controller':controllerName,
'action' :actionName,
'id':id,
'message':msg
]
* /

then:我收到一张地图, message-value是事件的标题
eventCrumb.message == event.title
}
}

请注意EventController中注释掉的方法


  1. 为什么代码段会导致无法获取属性'消息'关于null对象

  2. 如何正确设置代码片段?

  3. 通常,我将不需要任何当使用 Spock 时, mockTagLib mockController mockLogging GrailsUnitTestCase函数?

  4. ol>

    解决方案

    如果您正在对控制器进行单元测试,则会有一个约定为您自动设置控制器。只需在你的测试中引用控制器如下:

      import grails .plugin.spock。* 

    class EventControllerSpec extends ControllerSpec {

    def从事件创建面包屑(){
    given:我有一个named事件
    def event =模拟(事件)
    event.title>> 'sprock和船员的空间之旅'

    当:我创建一个面包屑
    def eventCrumb = controller.createCrumb(Event,show,1 ,event.title)

    / *
    private Map createCrumb(String controllerName,String actionName,String id,String msg){
    msg =(msg?msg:cr。面包屑。$ {controllerName}。$ {actionName})
    ['controller':controllerName,$ b $'action':actionName,
    'id':id,
    'message ':msg
    ]
    * /

    然后:我收到一个地图,其中的消息值是事件的标题
    eventCrumb.message ==事件.title
    }
    }

    您不需要明确地模拟控制器作为 ControllerSpec 为你做,但是,你可能需要模拟你的控制器正在使用的其他元素。有时候通过控制器的元类添加这些元素就足够了

    import grails.plugin.spock.*
    
    class EventControllerSpec extends ControllerSpec {
    
        def "Creating a breadcrumb from an event"() {
            given: "I have a named event"
            def eventController = Mock(EventController)
            def event   = Mock(Event)
            event.title >> 'Space-Journey with Sprock and the Crew'
            event.title == 'Space-Journey with Sprock and the Crew'
    
            when: "I create a breadcrumb from it"
            def eventCrumb = eventController.createCrumb("Event", "show", "1", event.title)
    
            /*
            private Map createCrumb (String controllerName, String actionName, String id, String msg) {
            msg = (msg ? msg : "cr.breadcrumb.${controllerName}.${actionName}")
            [ 'controller':controllerName,
            'action':actionName,
            'id':id,
            'message':msg
            ]
             */
    
            then: "I receive a map where the message-value is the events' title"
            eventCrumb.message == event.title
        }
    }
    

    note the commented out method which is in the EventController

    1. Why does the snippet cause "Cannot get property 'message' on null object"?
    2. How can I setup the snippet correctly?
    3. Generally, will/won't I need any of the mockTagLib, mockController, mockLogging GrailsUnitTestCase functions when using Spock?

    解决方案

    If you are unit testing a controller there is a convention which automatically sets the controller up for you. Just refer to the controller in your test as follows;

    import grails.plugin.spock.*
    
    class EventControllerSpec extends ControllerSpec {
    
      def "Creating a breadcrumb from an event"() {
        given: "I have a named event"
        def event = Mock(Event)
        event.title >> 'Space-Journey with Sprock and the Crew'
    
        when: "I create a breadcrumb from it"
        def eventCrumb = controller.createCrumb("Event", "show", "1", event.title)
    
        /*
        private Map createCrumb (String controllerName, String actionName, String id, String msg) {
        msg = (msg ? msg : "cr.breadcrumb.${controllerName}.${actionName}")
        [ 'controller':controllerName,
        'action':actionName,
        'id':id,
        'message':msg
        ]
         */
    
        then: "I receive a map where the message-value is the events' title"
        eventCrumb.message == event.title
      }
    }
    

    You don't need to explicitly mock the controller as ControllerSpec does it for you, however, you may need to mock other elements that your controller is using. Sometimes it is sufficient to add these through the controller's metaclass

    这篇关于为什么这个方法返回null,即使底层控制器使用Spock的Mock()模拟?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆