Issue
I want to create a JUnit test for my void method. The method has no parameter. Testing with methods that have a return value is clear to me but the void methods cause me difficulties especially when they contain maps and lists.
In my example I want to check in a HashMap if the word "car" occurs in this index and at the end I want to output all indexes in which the word "car" occurs.
public class Car {
private Map<Integer, String> carHashMap = new HashMap<>();
private ArrayList<Integer> showCarsInMap = new ArrayList<>();
public void putCarText() {
carHashMap.put(1, "this car is very fast car");
carHashMap.put(2, "i have a old car");
carHashMap.put(3, "my first car was an mercedes and my second car was an audi");
carHashMap.put(4, "today is a good day");
carHashMap.put(5, "car car car car");
}
public void countWordCar() {
for (Map.Entry<Integer, String> entrySection : carHashMap.entrySet()) {
if (entrySection.getValue().contains("car")) {
showCarsInMap.add(entrySection.getKey());
}
}
}
public void printShowCarsInMap() {
System.out.println(showCarsInMap);
}
}
I have created a JUnit test class but I can't get any further. I want to examine in my test in which index the word "car" occurs. This case Java testing a method with JUnit (void) has helped me a bit but since I don't have a parameter it is still hard for me to create a proper test case.
class CarTest {
Car car;
Map<Integer, String> carHashMap;
@BeforeEach
void setUp() {
car = new Car();
carHashMap = new HashMap<>();
ArrayList<Integer> showCarsInMap = new ArrayList<>();
carHashMap.put(1, "this car is very fast car");
carHashMap.put(2, "i have a old car");
carHashMap.put(3, "my first car was an mercedes and my second car was an audi");
carHashMap.put(4, "today is a good day");
carHashMap.put(5, "car car car car");
}
@Test
void countWordCarSize() {
assertEquals(5, carHashMap.size());
}
@Test
void countWordCar() {
assertEquals();
}
}
As far as I know, there are various possibilities with "Mockito" since we did not have that in the university, it may or should not be used.
Solution
Most of the time the fact that you are unable to test something means that the code is not designed properly.
In your case, your Car class's behavior is entirely internal and it is not possible to test it without additional tools.
But simple redesign may help you achieving your goal. You can in example move your counting method to a separate class and use it inside your car class.
public class CarCounter {
public List<Integer> countWordCar(Map<Integer, String> carMap) {
List<Integer> showCarsInMap = new ArrayList<>();
for (Map.Entry<Integer, String> entrySection : carMap.entrySet()) {
if (entrySection.getValue().contains("car")) {
showCarsInMap.add(entrySection.getKey());
}
}
return showCarsInMap;
}
}
And then you can test it like that:
class CarCounterTest {
@Test
void countCars() {
Map<Integer, String> carHashMap = new HashMap<>();
carHashMap.put(1, "this car is very fast car");
carHashMap.put(2, "i have a old car");
carHashMap.put(3, "my first car was an mercedes and my second car was an audi");
carHashMap.put(4, "today is a good day");
carHashMap.put(5, "car car car car");
CarCounter counter = new CarCounter();
List<Integer> results = counter.countWordCar(carHashMap);
assertEquals(4, results.size());
}
}
And use the counter in your car class like that:
public class Car {
...
private final CarCounter carCounter;
public Car(CarCounter carCounter) {
this.carCounter = carCounter;
}
...
public void countWordCar() {
showCarsInMap = carCounter.countWordCar(carHashMap);
}
...
}
In order to avoid designing classes that are difficult to test/maintain, you can take a look at TDD approach. It basically means that you run your unit tests first before the actual implementation. You will spot immediately if the methods that you write are easy to test and use. You can read more about it here: https://www.guru99.com/test-driven-development.html
Also, to design maintainable classes, take a look at SOLID concepts. They are set or rule which one should follow in order to design extendable and maintainable code. You can read more about it here: https://medium.com/mindorks/solid-principles-explained-with-examples-79d1ce114ace
Answered By - CaptainAye
Answer Checked By - David Goodson (JavaFixing Volunteer)