用spock测试void简单方法
test void simple method with spock
我有以下方法需要测试:
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)
问题是什么以及如何解决,谢谢!
有什么好的方法可以测试这个方法吗?
取决于你想测试什么。首先,您必须使用 Mock 或 Spy 才能测试调用计数。
例如,您可以测试 getFileName()
方法是否从 updateSpec()
方法调用,以及是否使用 '1'
参数调用,如下所示:
def "update spec"() {
given:
Person person = Spy(Person)
when:
person.updateSpec('1')
then:
1 * person.getFileName('1')
}
如果你真的需要测试File.delete()
是否被调用,那么最好稍微改变Person
class,因为你需要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
class 并在其上测试调用。
您只能定义规范下的对象与其模拟依赖项之间的交互。但是,在您的示例中,您是 "specifying" 与 File
class 的交互,而不是模拟对象。参见 Spock 的 Interaction Based Testing。从技术上讲,您可以 achieve/change 按照@cgrim 回答中的建议实现您的目标。或者您可以使用诸如 PowerMock (w/o Spock) 之类的工具来模拟几乎所有东西,但请记住,这种技术只能作为最后的手段。基本上,如果您遵循最佳设计实践,那么您将永远不需要此类工具。除非你必须处理一些遗留代码
我有以下方法需要测试:
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)
问题是什么以及如何解决,谢谢!
有什么好的方法可以测试这个方法吗?
取决于你想测试什么。首先,您必须使用 Mock 或 Spy 才能测试调用计数。
例如,您可以测试 getFileName()
方法是否从 updateSpec()
方法调用,以及是否使用 '1'
参数调用,如下所示:
def "update spec"() {
given:
Person person = Spy(Person)
when:
person.updateSpec('1')
then:
1 * person.getFileName('1')
}
如果你真的需要测试File.delete()
是否被调用,那么最好稍微改变Person
class,因为你需要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
class 并在其上测试调用。
您只能定义规范下的对象与其模拟依赖项之间的交互。但是,在您的示例中,您是 "specifying" 与 File
class 的交互,而不是模拟对象。参见 Spock 的 Interaction Based Testing。从技术上讲,您可以 achieve/change 按照@cgrim 回答中的建议实现您的目标。或者您可以使用诸如 PowerMock (w/o Spock) 之类的工具来模拟几乎所有东西,但请记住,这种技术只能作为最后的手段。基本上,如果您遵循最佳设计实践,那么您将永远不需要此类工具。除非你必须处理一些遗留代码