如何验证间谍对象方法的论证

时间:2014-02-04 20:05:53

标签: spock

我有一个方法save()的课程:

public class FilesystemImagePersistenceStrategy implements ImagePersistenceStrategy {
    public void save(MultipartFile file, Image image) {
        File dest = createFile(image);
        writeToFile(file, dest);
    }

    // protected to allow spying
    protected void writeToFile(MultipartFile file, File dest) throws IOException {
        IOUtils.copy(file.getInputStream(), new FileOutputStream(dest));
    }
}

现在我想在保存之前检查文件的名称:

class FilesystemImagePersistenceStrategyTest extends Specification {
    private ImagePersistenceStrategy strategy = Spy(FilesystemImagePersistenceStrategy)
    private MultipartFile multipartFile = Mock()
    private Image image = TestObjects.createImage()

    def "save() should gives proper name to the file"() {
        given:
            String expectedFileName = ...
        when:
            strategy.save(multipartFile, image)
        then:
            1 * strategy.writeToFile({ MultipartFile file, File dest ->
                assert dest.name == expectedFileName
                return true
            })
    }
}

但不幸的是它不起作用,而是调用了真正的方法......

为什么会这样?以及如何检查方法的论点?

P.S。我还在http://meetspock.appspot.com/script/5741031244955648

提供了一个示例

我最终得到了以下内容:

    1 * strategy.writeToFile(
        multipartFile,
        { assert it.name == expectedFileName; return true }
    ) >> {}

assert调用需要向我显示很好的错误消息,如下所示:

it.name != expectedFileName
|  |    |  |
|  1.png|  2.png
|       false
/tmp/1.png

当测试失败时,还需要return true。如果没有这个语句,闭包将返回false,并且此方法不会被视为候选(并且将执行实际方法)。

2 个答案:

答案 0 :(得分:4)

1 * strategy.writeToFile指定的参数约束是错误的。每个参数需要有一个约束,约束不能包含断言语句。此外,如果要将间谍用作部分模拟,则需要通过提供存根响应(在这种情况下“不执行任何操作”)来抑制默认响应(调用实际方法)。这导致:

...
then:
1 * strategy.writeToFile(multipartFile, { it.name == expectedFileName }) >> {}

可以简化为:

...
then:
1 * strategy.writeToFile(multipartFile, expectedFileName) >> {}

答案 1 :(得分:0)

对于mock上的多重性和断言,我使用了以下内容:

then:
numberOfCalls * mock.accept(_) >> {ArgType arg ->
    assert arg.id == my.id
    assert arg.minSerial == my.min()
    assert arg.maxSerial == my.max()
}