Spock 使用 table 将列表设置为参数
Spock set list as parameter by using table
有一个简单的 class:
class Person {
private int age;
private String name;
public String getName(){return this.name;}
public int getAge(){return this.age;}
public void setName(String name){this.name = name;}
public void setAge(int age){this.age = age;}
}
并且我在 SearchPeople
接口中有方法 getPersonNameWithPrefix()
和 getPeopleNames()
,在 SearchPeopleImpl
中实现:
class SearchPeopleImpl implements SearchPeople {
public String getPersonNameWithPrefix(Person person){
return "prefix" + person.getName();
}
public List<String> getPeopleNames(List<Person> peopleList){
return peopleList.stream().map(Person::getName).collect(Collectors.toList());
}
}
我想在我的测试中使用参数,它看起来像:
def 'test Person name'(){
given:
def searchPeople = new SearchPeopleImpl ()
def person = Mock(Person){
getName() >> a
}
when:
def name = searchPeople.getPersonNameWithPrefix(person)
then:
name == b
where:
a | b
"AA" | "prefixAA"
"BB" | "prefixBB"
"CC" | "prefixCC"
}
效果很好,但我在测试第二种方法时遇到了问题。如何将元素列表放入 table
(在 where
部分),将其用作方法参数,然后期望另一个对象列表?我的意思是我想声明一些 Person
对象列表,然后检查该方法 returns 正确的 Strings
列表
@更新
那么有什么办法可以做这样的事情:
def 'test getting persons names'(){
given:
def searchPeople = new SearchPeopleImpl()
when:
def names = searchPeople.getPeopleNames(a)
then:
names == b
where:
a | b
["AA","BB"].collect{ x -> Mock(Person){ getName() >> x } } | [["AA", "BB"]]
["CC"].collect{ x -> Mock(Person){ getName() >> x } } | [["CC"]]
["DD","EE","FD"].collect{ x -> Mock(Person){ getName() >> x } } | [["DD","EE","FD"]]
}
或:
def 'check double2 return value'(){
given:
def searchPeople = new SearchPeopleImpl()
when:
def names = searchPeople.getPeopleNames(a)
then:
names == b
where:
people1 << [
["AA","BB"].collect{ x ->
Mock(Person){
getName() >> x
}
}
]
people2 << [
["CC"].collect{ x ->
Mock(Person){
getName() >> x
}
}
]
names1 << [["AA", "BB"]]
names2 << [["CC"]]
a | b
people1 | names1
people2 | names2
}
我只想用table设置参数,但有可能我完全错了。
@UPDATE 有一个错误:
check double return value[0](com.test.myPlugin.api.SearchPeopleSpec) Time elapsed: 0.125 sec <<< FAILURE!
Condition not satisfied:
names == b
| | |
| | [[AA, BB]]
| false
[AA, BB]
并且每一行都有相同的错误。
List
的实例可以在数据驱动测试中以完全相同的方式使用。看看下面的例子:
class PersonSpec extends Specification {
def 'test getting persons names'() {
given:
def searchPeople = new SearchPeopleImpl()
when:
def result = searchPeople.getPeopleNames(names)
then:
result == expectedNames
where:
names << [
["AA", "BB"].collect { n ->
Mock(Person) {
getName() >> n
}
}
]
expectedNames << [["AA", "BB"]]
}
}
注意 where 块中的双括号。它必须以这种方式指定,因为如果只使用一对,每个参数将单独传递而不是传递整个列表。
您实际上可以将数据表与变量赋值 (docs) 结合起来,从而提供更清晰的测试:
def 'test getting persons names'(){
given:
def searchPeople = new SearchPeopleImpl()
when:
def names = searchPeople.getPeopleNames(input)
then:
names == expected
where:
a | expected
["AA","BB"] | [["AA", "BB"]]
["CC"] | [["CC"]]
["DD","EE","FD"] | [["DD","EE","FD"]]
input = a.collect{ new Person(name: it) }
}
此外,如果您需要验证,请仅使用 Mock
,例如,如果您仅将其用作协作者,请使用 1 * mock.method()
,而不是使用 Stub
来明确您的意图。此外,当您可以通过 bean 构造函数构造它们时,切勿模拟简单的 POJO。
有一个简单的 class:
class Person {
private int age;
private String name;
public String getName(){return this.name;}
public int getAge(){return this.age;}
public void setName(String name){this.name = name;}
public void setAge(int age){this.age = age;}
}
并且我在 SearchPeople
接口中有方法 getPersonNameWithPrefix()
和 getPeopleNames()
,在 SearchPeopleImpl
中实现:
class SearchPeopleImpl implements SearchPeople {
public String getPersonNameWithPrefix(Person person){
return "prefix" + person.getName();
}
public List<String> getPeopleNames(List<Person> peopleList){
return peopleList.stream().map(Person::getName).collect(Collectors.toList());
}
}
我想在我的测试中使用参数,它看起来像:
def 'test Person name'(){
given:
def searchPeople = new SearchPeopleImpl ()
def person = Mock(Person){
getName() >> a
}
when:
def name = searchPeople.getPersonNameWithPrefix(person)
then:
name == b
where:
a | b
"AA" | "prefixAA"
"BB" | "prefixBB"
"CC" | "prefixCC"
}
效果很好,但我在测试第二种方法时遇到了问题。如何将元素列表放入 table
(在 where
部分),将其用作方法参数,然后期望另一个对象列表?我的意思是我想声明一些 Person
对象列表,然后检查该方法 returns 正确的 Strings
@更新 那么有什么办法可以做这样的事情:
def 'test getting persons names'(){
given:
def searchPeople = new SearchPeopleImpl()
when:
def names = searchPeople.getPeopleNames(a)
then:
names == b
where:
a | b
["AA","BB"].collect{ x -> Mock(Person){ getName() >> x } } | [["AA", "BB"]]
["CC"].collect{ x -> Mock(Person){ getName() >> x } } | [["CC"]]
["DD","EE","FD"].collect{ x -> Mock(Person){ getName() >> x } } | [["DD","EE","FD"]]
}
或:
def 'check double2 return value'(){
given:
def searchPeople = new SearchPeopleImpl()
when:
def names = searchPeople.getPeopleNames(a)
then:
names == b
where:
people1 << [
["AA","BB"].collect{ x ->
Mock(Person){
getName() >> x
}
}
]
people2 << [
["CC"].collect{ x ->
Mock(Person){
getName() >> x
}
}
]
names1 << [["AA", "BB"]]
names2 << [["CC"]]
a | b
people1 | names1
people2 | names2
}
我只想用table设置参数,但有可能我完全错了。
@UPDATE 有一个错误:
check double return value[0](com.test.myPlugin.api.SearchPeopleSpec) Time elapsed: 0.125 sec <<< FAILURE!
Condition not satisfied:
names == b
| | |
| | [[AA, BB]]
| false
[AA, BB]
并且每一行都有相同的错误。
List
的实例可以在数据驱动测试中以完全相同的方式使用。看看下面的例子:
class PersonSpec extends Specification {
def 'test getting persons names'() {
given:
def searchPeople = new SearchPeopleImpl()
when:
def result = searchPeople.getPeopleNames(names)
then:
result == expectedNames
where:
names << [
["AA", "BB"].collect { n ->
Mock(Person) {
getName() >> n
}
}
]
expectedNames << [["AA", "BB"]]
}
}
注意 where 块中的双括号。它必须以这种方式指定,因为如果只使用一对,每个参数将单独传递而不是传递整个列表。
您实际上可以将数据表与变量赋值 (docs) 结合起来,从而提供更清晰的测试:
def 'test getting persons names'(){
given:
def searchPeople = new SearchPeopleImpl()
when:
def names = searchPeople.getPeopleNames(input)
then:
names == expected
where:
a | expected
["AA","BB"] | [["AA", "BB"]]
["CC"] | [["CC"]]
["DD","EE","FD"] | [["DD","EE","FD"]]
input = a.collect{ new Person(name: it) }
}
此外,如果您需要验证,请仅使用 Mock
,例如,如果您仅将其用作协作者,请使用 1 * mock.method()
,而不是使用 Stub
来明确您的意图。此外,当您可以通过 bean 构造函数构造它们时,切勿模拟简单的 POJO。