What is the point in unit testing to return data?

Consider a scenario in which I mock a specific service and its method.

Employee emp = mock(Employee.class); when(emp.getName(1)).thenReturn("Jim"); when(emp.getName(2)).thenReturn("Mark"); //assert assertEquals("Jim", emp.getName(1)); assertEquals("Mark", emp.getName(2)); 

In the above code, when emp.getName(1) is called, then mock will return Jim and when emp.getName(2) will be called mock, it will return Mark. My question is that I am declaring Mock behavior and checking its assertEquals , what is the point of having the above (or the same) assert statements? Obviously, this will pass. it's just checking 3==(1+2) , what's the point? When will these tests fail (other than changing the return type and parameter type)?

+7
java unit-testing junit mockito mocking
source share
5 answers

As you noted, such tests are pointless (unless you write unit test for Mockito itself, of course :-)).

The point of mocking is to remove external dependencies so that you can test your code without using code from other classes. For example, suppose you have a class that uses the Employee class that you described:

 public class EmployeeExaminer { public boolean isJim(Employee e, int i) { return "Jim".equals(e.getName(i)); } } 

And you want to write unit test for it. Of course, you can use the actual Employee class, but then your test will no longer be unit -test - it will depend on the implementation of Employee . Here's where the mockery comes in handy - it allows you to replace Employee with predictable behavior so you can write a stable unit test:

 // The object under test EmployeeExaminer ee = new EmployeeExaminer(); // A mock Employee used for tests: Employee emp = mock(Employee.class); when(emp.getName(1)).thenReturn("Jim"); when(emp.getName(2)).thenReturn("Mark"); // Assert EmployeeExaminer behavior: assertTrue(ee.isJim(emp, 1)); assertFalse(ee.isJim(emp, 2)); 
+5
source share

There is no point in this test.

Mocks are only useful for injecting dependencies into classes and testing that a particular behavior interacts correctly with this dependency, or so that you can test any behavior that requires an interface that you do not need in the test that you write.

Mocking the class you are testing means that you are not even testing this class.

If the emp variable was inserted into another class, and then this class was tested, I could see some point in it.

+1
source share

The above test file is trying to test POJO.

In fact, you can ignore POJO testing, or, in other words, they are automatically checked when testing other core functions. (there are also utilities like mean- beans for testing POJO)

The purpose of unit testing is to test functionality without connecting to any external systems. If you connect to any external system, this is considered integration testing.

Mocking an object helps to create mock objects that cannot be created during unit testing, and behavior / logic testing based on the fact that the mocked object is returned (or the real object when connected to an external system).

+1
source share

Mocks are structures that mimic the behavior of external dependencies that you / cannot have or that cannot work properly in the context of your test, because they depend on other external systems (for example, connecting to the server). Therefore, the test, as you described, is really not very useful, because you are basically trying to check the simulated behavior of your layouts and nothing more.

A better example is the EmployeeValidator class, which depends on another EmployeeService system that sends a request to an external server. Perhaps the server is not available in the current context of your test, so you need to make fun of the service that makes the request and simulate the behavior of this.

 class EmployeeValidator { private final EmployeeService service; public EmployeeValidator(EmployeeService service) { this.service = service; } public List<Employee> employeesWithMaxSalary(int maxSalary) { List<Employee> allEmployees = service.getAll(); // Possible call to external system via HTTP or so. List<Employee> filtered = new LinkedList<>(); for(Employee e : allEmployees) { if(e.getSalary() <= maxSalary) { filtered.add(e); } } return filtered; } } 

You can then write a test that mocks EmployeeService and simulates a call to an external system. After that, you can verify that everything went as planned.

 @Test public void shouldContainAllEmployeesWithSalaryFiveThousand() { // Given - Define behaviour EmployeeService mockService = mock(EmployeeService.class); when(mockService.getAll()).thenReturn(createEmployeeList()); // When - Operate the system under test // Inject the mock EmployeeValidator ev = new EmployeeValidator(mockService); // System calls EmployeeService#getAll() internally but this is mocked away here List<Employee> filtered = ev.employeesWithMaxSalary(5000); // Then - Check correct results assertThat(filtered.size(), is(3)); // There are only 3 employees with Salary <= 5000 verify(mockService, times(1)).getAll(); // The service method was called exactly one time. } private List<Employee> createEmployeeList() { // Create some dummy Employees } 
+1
source share

In your case, you are testing a getter, I don’t know why you are testing it, and don’t know why you should mock it. From the code you provide, this is useless.

There are many scenarios in which it makes sense when you write a unit test, you should be pragmatic, you should test the behavior and layout of dependencies.

You are not testing behavior here, and you are mocking the class being tested.

0
source share

All Articles