In Spock testing, I would like to be able to change the values of the variables inside the method.
For example, I would like to change the value of uName to 'John'. or for another test, change the value of uCat to "seller" when doing the testing. How can I make sure in the testing that the 2 methods: postComment and sendEmails inside the else statements get executed.
class userService {
void userComment()
{
def uName = "test123"
def uCat = Category.getUserCategory(uName)
if (uCat.empty){
println("no categories to process")
}
else
{
postComment(uName)
batchJob.sendEmail(uName)
}
}
}
class userServiceSpec extends Specification{
def "test userComment"()
{
given:
?????
when:
?????
then:
1 * postComment(_)
then:
1* batchJob.sendEmail(_)
}
}
For uName
, you need to inject the username as a constructor param or add a method param in your service. A method param probably makes the most sense.
Because you made getUserCategory
a static method, you have to use GroovySpy
but it's usually an indication you're doing something wrong. You should really make a CategoryService
that is injected into your userService
class userService {
void userComment(uName)
{
def uCat = Category.getUserCategory(uName)
if (uCat.empty){
println("no categories to process")
}
else
{
postComment(uName)
batchJob.sendEmail(uName)
}
}
}
class userServiceSpec extends Specification{
def userService = Spy(userService)
def CategorySpy = GroovySpy(Category, global: true)
def "test userComment"()
{
given:
def uName = "test123"
when: 'we have a category found'
userService.userComment(uName)
then: 'return user cat of "seller" '
1 * CategorySpy.getUserCategory(uName) >> 'seller'
1 * postComment(uName)
then:
1 * batchJob.sendEmail(uName)
when: 'we have an "empty" category'
userService.userComment(uName)
then: 'return a category where uCat.empty will be true'
1 * CategorySpy.getUserCategory(uName) >> []
0 * postComment(uName)
0 * batchJob.sendEmail(uName)
}
}
Some Spock Framework slides that might help
All of this said, you should really refactor to make your classes easier to test. Dependency injection is your friend. Never hardcode values in a class like that.