英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论