I am new to writing unit tests and having a difficult time understanding a lot of the concepts involved.
I have a method in a class that I am trying to write a unit test for. See below:
public class MyServiceImpl extends MyServiceBase implements MyService {
@Override
@Transactional
public void deletePerson(long id) {
Person person = findOrThrow(Person.class, id);
entityManager.remove(person);
}
}
The findOrThrow
method is protected in the MyServiceBase
class. I cannot change the access modifier as it would affect too much, and this is more so a low-impact way for me to learn unit testing.
I have tried to put together unit tests, either by reading documentation or by using ChatGPT to help with explanations, and my head spins by the amount of directions which are suggested. I'm operating under the assumption that I have to somehow "mock" or control what returns when findOrThrow
is called, but this is yielding problems - I get a compilation error stating that findOrThrow
is protected. ChatGPT suggests I spy on MyService
, but doing so does not help the compilation error.
I'm just not even sure if that is the correct approach. I am looking for something simple that will not only test my deletePerson
method, but help me with a beginner's understanding of writing a unit test and mocking objects, as well as controlling methods within the method I'm testing.
Where do I start? Does anyone have any suggestions on how to go about writing a unit test for this? Am I thinking about this the correct way or am I taking the wrong approach?
What is the correct approach here?
You need to look into the base class and see what dependencies it has w.r.t. the findOrThrow
method (probably the entityManager
, but possibly more). Those dependencies (external references) are candidates for mocking, but not necessarily--it depends on how "expensive" they are to create and how easy they are to control.
Unit testing is the art of allowing your unit to be tested in isolation.
What is your unit? Normally it's a class, but it can be a cohesive set of classes, a module or even a subsystem. You decide.
Isolation means that each test case should be independent on the outcome of previous test cases and the state of the unit's dependencies. The dependencies behavior should also be predictable.