使用MOP保存参数方法

时间:2014-06-27 09:31:17

标签: groovy metaprogramming spock metaclass

我正在与Spock和第三方应用进行一些集成测试。现在我正在努力解决一个问题,我不确定我是否正确接近这个问题。

在其中一个测试中,我连接到第三方服务以获取阵列中的某些信息。然后将这些项中的每一个传递给另一个方法以单独处理它们。

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

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

get3rdPartyItems.each {
   processItem(it)
}

然后我有一个使用方法 get3rdPartyItems()连接到真正的第三方服务的测试,其中我测试的是,当项目返回方法 get3rdPartyItems时,多次调用processItem ()

我想要做的是将其中一个项目保存为@Shared变量来编写另一个测试,以便知道该项目已正确处理,因为我不想模拟从第三方服务检索到的内容,因为我想要真实数据。

基本上,这就是我在做的事情:

@Shared def globalItem

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

任何线索如何实现这一目标?我可能过头了,所以我愿意改变解决方案。

2 个答案:

答案 0 :(得分:0)

不确定这是否是您想要的,因为很难从代码中看到您现有的结构,并且代码不能按原样运行,但是给出了这个类:

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

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

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

你可以这样做:

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()

答案 1 :(得分:0)

简单来说,这应该是在传递多个参数时将参数传递给元方法的方法:

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()