【问题标题】:test void simple method with spock用 spock 测试 void 简单方法
【发布时间】:2019-02-13 17:24:58
【问题描述】:

我有以下方法需要测试:

class Person {

    String getFileName(String number) {
         return "file"+number
    }

    void updateSpec(String number) {
         new File(getFileName(number)).delete()
    }
}

我尝试像这样创建测试用例:

def "update spec"() {
        given:
            Person person = new Person()

        when:
            person.updateSpec('1')

        then:
            1 * File.delete()
    }

上面写着:

Too few invocations for:

1 * File.delete()   (0 invocations)

问题是什么以及如何解决,谢谢!

有没有什么好的方法可以测试这个方法?

【问题讨论】:

  • Person类怎么知道文件在哪个目录?

标签: groovy spock


【解决方案1】:

取决于您要测试什么。首先,您必须使用 Mock 或 Spy 才能测试调用计数。

例如,您可以测试是否从 updateSpec() 方法调用了 getFileName() 方法,以及是否使用 '1' 参数调用它,如下所示:

def "update spec"() {
    given:
    Person person = Spy(Person)

    when:
    person.updateSpec('1')

    then:
    1 * person.getFileName('1')
}

如果你真的需要测试File.delete()是否被调用,那么最好稍微改变Person类,因为你需要File mock,你可以在上面检查调用计数:

class Person {
    File getFile(String number) {
        return new File("file" + number)
    }

    void updateSpec(String number) {
        getFile(number).delete()
    }
}

然后可以进行测试:

def "File delete was called"() {
    given:
    File file = Mock(File)
    Person person = Spy(Person)
    person.getFile(_) >> file

    when:
    person.updateSpec('1')

    then:
    1 * file.delete()
}

另一种选择是注入一些FileService,它将File.delete() 方法封装到Person 类中并在其上测试调用。

【讨论】:

    【解决方案2】:

    您只能定义规范下的对象与其模拟依赖项之间的交互。但是,在您的示例中,您正在“指定”与 File 类的交互,而不是模拟对象。请参阅 Spock 的Interaction Based Testing。从技术上讲,您可以按照@cgrim 答案中的建议实现/更改您的目标。或者您可以使用诸如 PowerMock(不带 Spock)之类的工具来模拟几乎所有东西,但请记住,这种技术只能作为最后的手段。基本上,如果您坚持最佳设计实践,那么您将永远不需要这些工具。除非你必须处理一些遗留代码

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-02
      • 2017-05-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多