What would be the most exhaustive tests that I could write for the following piece of code?
public void deleteFromPerson(person person) {
person = personRepository.returnPerson(person.getId());
personRepository.delete(person);
}
This method is within a service
class. The method makes calls to a JpaRepository that then calls it's delete()
method on the entity.
If it is not possible to test if the entity is being deleted, is there any other tests cases
I can run on the method?
There are two testing strategies. One is unit testing, i.e. making sure your service works. The other is integration/end-to-end testing, i.e. making sure everything plays nicely together.
You unit test stuff you own, you integration test everything you have. This is a pretty rough example using just your statement, plus some made up stuff where I can't fill in the blanks.
Unit Tests
Using Mockito
PersonRepository personRepository = mock(PersonRepository.class);
@TestSubject
PersonService personService = new PersonService():
@Test
public void unitTest() {
personService.setPersonRepository(personRepository);
Person person = new Person(1L);
Person person2 = new Person(1L);
when(personRepository.returnPerson(1L)).thenReturn(person2); //expect a fetch, return a "fetched" person;
personService.deleteFromPerson(person);
verify(personRepository, times(1)).delete(person2); //pretty sure it is verify after call
}
Using EasyMock...
@Mock
PersonRepository personRepository; //assuming it is autowired
@TestSubject
PersonService personService = new PersonService():
@Test
public void unitTest() {
Person person = new Person(1L);
Person person2 = new Person(1L);
EasyMock.expect(personRepository.returnPerson(1L)).andReturn(person2); //expect a fetch, return a "fetched" person;
personRepository.delete(person2);
EasyMock.expectLastCall(); //expect a delete for person2 we plan to delete
replayAll();
personService.deleteFromPerson(person);
verifyAll(); //make sure everything was called
}
Yes, this test looks like it is written rigidly, but that's really all you're testing in the unit test, anyways. You want the DB to fetch a Person from the database using an argument, hence why there are two Person
objects, and you expect to delete that passed Person
object, which is why you expect the call. Simple method yields simple test. You basically want to ensure you're interacting with your repository as you expect. Repository could be broken or null in actual implementation, but that doesn't change the fact that your service is implemented correctly.
Integration Tests
On the other hand, if you want to do an integration test, no mocking is used. Instead, you'll need to wire up everything like a test DB and repo. I'll leave that up to you since there's no reference for implementation.
@Test
public void integrationTestForAddAndDelete() {
Person person = createDummyPersonForInsertion(); //static method that creates a test Person for you
Person comparePerson;
//make sure we haven't added the person yet
Assert.assertNull(personService.getPerson(person));
//add the Person
comparePerson = personService.addPerson(person);
Assert.assertNotNull(personService.getPerson(person));
//add a rigorous compare method to make sure contents are the same, i.e. nothing is lost or transmuted incorrectly, ignoring ID if that is autogen
//alternatively, you can create a unit test just for Person
Assert.assertEquals(person, comparePerson);
//remove the Person
personService.deleteFromPerson(person);
Assert.assertNull(personService.getPerson(person));
//test for exception handling when you try to remove a non-existent person;
personService.deleteFromPerson(person);
//test for exception handling when you try to remove null
personService.deleteFromPerson(null);
}
In this case, you want to make sure your repo actually handles all the calls from the service. You know your service works from the unit test, but does the repo work from the service or have you configured something wrong