0

I am doing some integration tests with Spock with 3rd party apps. Now I am struggling with a problem that I am not sure wether I am approaching the issue properly or not.

In one of the tests I am connecting to a 3rd party service to get some information in an array. Then each of these items are passed to another method to process them individually.

def get3rdPartyItems = {
   [item1, item2, item3]
}

def processItem = { item ->
   //do something with item
}

get3rdPartyItems.each {
   processItem(it)
}

Then I have a test that connects to real 3rd party service using the method get3rdPartyItems() in which I am testing that processItem is called as many times as items has returned the method get3rdPartyItems().

What I am trying to do is to save one of the items as @Shared variable to write another test to know that the item is processed properly as I don't want to mock the content retrieved from the 3rd party service as I want real data.

Basically, this is what I am doing:

@Shared def globalItem

MyClass.metaClass.processItem = { i ->
   if (!globalItem)
      globalItem = i
   //And now I would need to call the original method processItem
}

Any clue how to achieve this? I am probably overheading too much so I am open to change the solution.

Fran García
  • 2,011
  • 16
  • 24

2 Answers2

0

Not sure if this is what you want, as it's hard to see your existing structure from the code and the code isn't runnable as-is, but given this class:

class MyClass {
    def get3rdPartyItems = {
        ['item1', 'item2', 'item3']
    }

    def processItem( item ) {
        println item
        //do something with item
    }

    def run() {
        get3rdPartyItems().each {
            processItem( it )
        }
    }
}

You can do this:

def globalItem
def oldProcessItem = MyClass.metaClass.getMetaMethod("processItem", Object)

MyClass.metaClass.processItem = { item ->
    if (!globalItem) {
        println "Setting global item to $item"
        globalItem = item
    }
    oldProcessItem.invoke( delegate, item )
}
def mc = new MyClass()
new MyClass().run()
tim_yates
  • 167,322
  • 27
  • 342
  • 338
0

Just as a matter of concision, that should be the way of passing the parameters to the metamethod in case you pass multiple parameters:

def globalItem
def oldProcessItem = MyClass.metaClass.getMetaMethod("processItem", ["",[:]] as Object[])

MyClass.metaClass.processItem = { String p1, Map p2 ->
    if (!globalItem) {
        println "Setting global item to $item"
        globalItem = p2
    }
    oldProcessItem.invoke( delegate, [p1,p2] as Object[] )
}
def mc = new MyClass()
new MyClass().run()
Fran García
  • 2,011
  • 16
  • 24