I'm trying to use a Spock Stub to mock a database/repository dependency in my service class, but I'm having an issue with the stub returning an unexpected value. I don't understand why the stub only works when I don't pass an argument to the mocked method.
given: 'I have client data'
Client client = new Client("Foo", "bar@baz.org")
and: 'a client repository always returns the id'
clientRepository = Stub(ClientRepository)
ClientEntity ce = new ClientEntity("Foo", "bar@baz.org")
clientRepository.create(ce) >> 1
when: 'I add the client'
ClientService clientService = new ClientServiceImpl(clientRepository)
Client addedClient = clientService.addClient(client)
then: 'The client object should be populated correctly'
addedClient.getId() == 1 // This fails b/c it's returning the id as 0
But when I use the _ argument the test passes:
given: 'I have client data'
Client client = new Client("Foo", "bar@baz.org")
and: 'a client repository always returns the id'
clientRepository = Stub(ClientRepository)
clientRepository.create(_) >> 1
when: 'I add the client'
ClientService clientService = new ClientServiceImpl(clientRepository)
Client addedClient = clientService.addClient(client)
then: 'The client object should be populated correctly'
addedClient.getId() == 1 // This passes b/c it's returning the id as 1
Here are the Service class
@Service
public class ClientServiceImpl implements ClientService{
private ClientRepository clientRepository;
@Autowired
ClientServiceImpl(ClientRepository clientRepository){
this.clientRepository = clientRepository;
}
@Override
public Client addClient(Client client){
ClientEntity clientEntity = new ClientEntity(
client.getName(),
client.getEmailAddress()
);
int id = clientRepository.create(clientEntity);
client.setId(id);
return client;
}
}
And the Spock dependency
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<version>1.3-groovy-2.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-spring</artifactId>
<version>1.3-groovy-2.5</version>
<scope>test</scope>
</dependency>
Thanks for the help!
If you do this
ClientEntity ce = new ClientEntity("Foo", "bar@baz.org")
clientRepository.create(ce) >> 1
and the stubbed interaction is not being executed, then because the method argument was not matched according to your expectation. My guess is that the equals(..)
method of ClientEntity
does not work as you expect it to and that the argument given to create(..)
is not exactly ce
but a copy of it which does not satisfy equals(..)
.
Solution: Fix your equals(..)
method.