I'm not sure if I'm misusing interaction based testing or if I'm doing something conceptionally wrong. I'm working on a Spring Boot Application (Kotlin) and my tests are using Spock/Groovy.
I have a class under test which invokes another service to query information. The class under test is supposed to cache results. However, I'm not able to mock a method with a return value AND check the number of invocations, because the mocked method always returns null as soon as I add the check for invocation.
I created an isolated example, which demonstrates the issue.
This is the class under test:
@Service
class DemoService(private val downstreamService: DownstreamService) {
fun demo(id: String): String {
val something = downstreamService.something(id)
return something
}
}
which is using this service:
@Service
class DownstreamService {
fun something(id: String): String {
return id
}
}
and this is how my tests look like:
class DemoServiceTest extends Specification {
def downStream = Mock(DownstreamService)
def demoService = new DemoService(downStream)
def "value check"() {
given:
def test = "my test string"
downStream.something(test) >> "xxx"
when:
def actual = demoService.demo(test)
then:
actual == "xxx" // works
}
def "invocation check"() {
given:
def test = "my test string"
downStream.something(test) >> "xxx"
when:
demoService.demo(test)
then:
1 * downStream.something(test) // works
}
def "combined check"() {
given:
def test = "my test string"
downStream.something(test) >> "xxx"
when:
def demo = demoService.demo(test)
then:
1 * downStream.something(test)
demo == "xxx" // fails because demo is null
}
}
The first two tests are working as expected but the last one fails because the return value is always null when I add the check for the invocation.
# This will not work
, the "not" in the sentence above is easy to miss... end of paragraph... visually hard to spot. Thank you. – Marengo