Reputation: 59
There is a simply 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;}
}
and I have a methods getPersonNameWithPrefix()
and getPeopleNames()
in SearchPeople
interface with implement in 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());
}
}
I want to use parameters in my test and it looks like:
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"
}
It works well but I have a problem with test my second method. How is it possible to put list of elements into table
(in where
section), use it as method parameter and then expect another list of objects? I mean that I want to declare a few list of Person
objects and then check that method returns correct list of Strings
@UPDATE So is there any way to do something like:
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"]]
}
or:
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
}
I just want to use table to set parameters but it is possible that i am totally wrong.
@UPDATE there is an error:
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]
and there is the same error for every row.
Upvotes: 1
Views: 5617
Reputation: 13242
You can actually combine the data tables with variable assignments (docs) which provides a much cleaner test:
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) }
}
Furthermore, only use Mock
if you need the validation, e.g., 1 * mock.method()
if you only use it as a collaborator use Stub
instead to make your intent clear. Also, never mock simple POJOs when you can just construct them via bean constructor.
Upvotes: 2
Reputation: 84844
An instance of List
can be used in exactly the same way in data-drive testing. Have a look at the following example:
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"]]
}
}
Note the double parens in where block. It must specified this way since if only single pair would be used every single argument will be passed separately instead of passing the whole list.
Upvotes: 3