如何创建一个 Spock 模拟对象,它在每次调用时都评估一个闭包?

huangapple go评论96阅读模式
英文:

How can I create a spock mock that evaluates a closure at every call?

问题

我有一个方法,它返回一个InputStream,以及一个测试案例,在测试案例中,我必须对该方法进行模拟:

def myMock = Mock(MyClass) {
    get(InputStream) >> new ByteArrayInputStream("bla bla".getBytes(Charset.defaultCharset()))
}

问题是,这个方法被调用多次,这意味着第二次输入流已经关闭并且为空。所以我使用了一个列表,提前填充了多个输入流的实例,像这样:

def myMock = Mock(MyClass) {
    get(InputStream) >>> ([ByteArrayInputStream] * numCalls)*.newInstance("bla bla".getBytes(Charset.defaultCharset()))
}

如果我在执行之前知道该方法的调用次数,这样是有效的。但我认为更优雅的方式是使用一个每次调用方法时都会计算的闭包。我遵循了这个答案,并尝试以下方式:

def myMock = Mock(MyClass) {
    get(InputStream) >>> [].withDefault{
        new ByteArrayInputStream("bla bla".getBytes(Charset.defaultCharset()))
    }
}

但这会导致get方法始终返回null。有没有办法解决这个问题?

英文:

I have a method which returns an InputStream and a test case in which I have to mock that method:

def myMock = Mock(MyClass) {
    get(InputStream) >> new ByteArrayInputStream("bla bla".getBytes(Charset.defaultCharset()))
}

The problem is that this method is called more than once which means that the second time the input stream is already closed and empty. So I used a list instead which i filled beforehand with multiple instances of the input stream like this:

def myMock = Mock(MyClass) {
    get(InputStream) >>> ([ByteArrayInputStream] * numCalls)*.newInstance("bla bla".getBytes(Charset.defaultCharset()))
}

which works if I know the number of calls to that method before the execution. But I think it would be more elegant to have a closure which is evaluated every time the method is called. I followed this answer and tried to do it this way:

def myMock = Mock(MyClass) {
    get(InputStream) >>> [].withDefault{
        new ByteArrayInputStream("bla bla".getBytes(Charset.defaultCharset()))
    }
}

But that causes the get method to always return null. Is there a way to solve this?

答案1

得分: 1

好的,原来我想得太多了。我这样解决了:

def myMock = Mock(MyClass) {
    get(InputStream) >> {new ByteArrayInputStream("bla bla".getBytes(Charset.defaultCharset()))}
}

所以只需将构造函数包装在闭包中,然后使用>>运算符,而不是>>>运算符,它就会像魔术般起作用。

英文:

OK, turns out I was overthinking. I solved like this:

def myMock = Mock(MyClass) {
    get(InputStream) >> {new ByteArrayInputStream("bla bla".getBytes(Charset.defaultCharset()))}
}

So just wrap the constructor in a closure and use the >> operator, not the >>> operator and it works like a charm.

huangapple
  • 本文由 发表于 2023年6月16日 15:42:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76487982.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定