I am trying out spock framework for writing unit test for a particular method in a service class but not able to mock response for a method.
Service class
@Service
@RequiredArgsConstructor
public class ServiceA {
private final RepositoryA repositoryA;
private final ServiceB serviceB;
public void methodUnderTest(String arg1,String arg2){
ObjectA objectA = repositoryA.someMethod(arg1, arg2); // here objectA is null
if (objectA != null) {
// Do something
}else{
// Do something else
}
}
}
I am not able to stub repositoryA.someMethod(arg1, arg2) for some reason.
Its returning null while running the test.
I have tried putting both mock and stub interaction in then block as suggested in another question but its not working for me.
Test class
class ServiceATest extends Specification {
@Shared ServiceA serviceA;
@Shared RepositoryA repositoryA = Mock(RepositoryA)
@Shared ServiceB serviceB = Mock(ServiceB)
def "test"() {
given:
serviceA = new ServiceA(repositoryA, serviceB);
ObjectA mockResponse = ObjectA.builder()
.field1("demo")
.field2("demo")
.field3(Instant.now().plus(3, ChronoUnit.DAYS))
.build();
when:
serviceA.methodUnderTest(arg1,arg2);
then:
1 * repositoryA.someMethod(arg1,arg2) >> mockResponse // this is not working as expected
}
}
Spock manual, chapter Scope of Interactions:
Why would you even want to share a mock? Sharing state is bad test design and should only be used as sparingly as possible for expensive objects. Mocks are cheap. Simply resist the reflex to make everything
@Shared, especially mocks. This kind of premature optimisation is equivalent to shooting your own foot.For reference, here is an MCVE reproducing your situation. It would have been your job to provide one:
Try it in the Groovy Web Console.