Search code examples
groovyspock

Update a Map in groovy spock framework


I have the below spock specification and want to update the map from data table. Can some body help achieve this

def "groovy map update"() {                                                   
        setup: "step1"                                                            

        Map json = [                                                              
                user :[                                                           
                        name : 'ABC'                                              
                ]]                                                                

        when: "step2"                                                             

        println ('Before modification:')                                          
        println (json)                                                            

        then: "step3"                                                             

        json.with {                                                               
            //user.name = value // this one works                                 
            (field) = value   // this one does not work                           
        }                                                                         

        println ('After modification:')                                           
        println (json)                                                            

        where:                                                                    
        field                               | value                               
        'user.name'                         | 'XYZ'                               

    }   

Solution

  • The then section is intended for asserts and not for updates etc. So you have to update the map in the when section and then test the result in the then section. For example like this:

    def "groovy map update"() {
        setup: 'create json'
        Map json = [user: [name: 'ABC']]
    
        when: 'update it'
        def target = json
        for (node in path - path.last()) {
            target = target[node]
        }
        target[path.last()] = value
    
        then: 'check the assignment'
        json.user.name == value
    
        where:
        path             | value
        ['user', 'name'] | 'XYZ'
    }
    

    One way how to update nested Map value can be by using list of path nodes instead of field notation and then iterate over them to obtain the last Map instance and set the value there:

    def target = json
    for (node in path - path.last()) {
        target = target[node]
    }
    target[path.last()] = value