Home > Back-end >  Unit Test for multiple condition in Java?
Unit Test for multiple condition in Java?

Time:03-16

I am new in Unit Testing and I have sometimes such situations with multiple conditions. However, I am not sure if I re-mock or verify the same cases for each test.

For example, I am trying to write Unit Tests for the following service method:

public void create(Request request) {
    
    // code omitted

    if (!employeeService.existsByUuid(uuid)) {
        throw new EntityNotFoundException("Not found");
    }

    EmployeeDTO employee = employeeService.save(...);
    
    if (!departmentService.existsByUuid(employee.getDepartment())) {
        throw new EntityNotFoundException("Not found");
    }
}

I think I need to write my tests for the following scenarios:

1. when employeeService.existsByUuid(uuid) == false, then throw new EntityNotFoundException. then verify employeeService.save() and departmentService.existsByUuid() is never called.

2. when employeeService.existsByUuid(uuid) == true then employeeService.save() is called and I assert the values. and then verify employeeService.save() and departmentService.existsByUuid() is never called.

3. when departmentService.existsByUuid() == false then throw new EntityNotFoundException. At this stage, I also mock employeeService.existsByUuid(uuid) as true so that test passes the first condition. However, I am not sure if do I need to assert the second part; employeeService.save() is called and I assert the values. Do I assert of the returned values or just verify that method is called 1 time. Because I already asserted its value and the 3rd test is just for the 3rd condition.

Any idea for this kind of scenarios when we have multiple condition and may need to re-test the same condition again and again?

CodePudding user response:

You should not try to test your code line by line, but with cases that cover a single meaningful scenario. So if you already have a case which checks a condition, you don't have to repeat those asserts in other test cases.

In your example I think these could be the core cases:

  1. if the UUID does not exist, an exception is thrown and the employee is not saved
  2. if the UUID exists, all the employee fields are saved correctly
  3. if the employee is saved, but the employee's department does not exist an exception is thrown

To test them you could do something like this:

EmployeeService employeeService = mock(EmployeeService.class);

case 1:

when(employeeService.existsByUuid(employeeUuid)).thenReturn(false);   
try {
    testObject.create(request);
    fail();
}
catch(EntityNotFoundException e) {
    verify(employeeService, never()).save(...);
}

case 2:

when(employeeService.existsByUuid(employeeUuid)).thenReturn(true); 
when(employeeService.existsByUuid(departmentUuid)).thenReturn(true);    
testObject.create(request);
verify(employeeService).save(field1, field2, ...);

case 3:

when(employeeService.existsByUuid(employeeUuid)).thenReturn(true);   
when(employeeService.existsByUuid(departmentUuid)).thenReturn(false);   
try {
    testObject.create(request);
    fail();
}
catch(EntityNotFoundException e) {
    // success
}

BTW you can also indicate expected exceptions in the @Test annotation, but then you cannot do any further checking on the results:

@Test(expected = EntityNotFoundException.class)
public void test3() {
    when(employeeService.existsByUuid(employeeUuid)).thenReturn(true);   
    when(employeeService.existsByUuid(departmentUuid)).thenReturn(false);   
    testObject.create(request);
}

CodePudding user response:

You can use mockito verify and assert throws to test your objectives something like below

    @Test
    public void testOne(){
        when(employeeService.existsByUuid(uuid)).thenReturn(false);

        assertThrows(EntityNotFoundException.class, () -> {
            create(request);
        });

        verify(employeeService, times(0)).save(eq(empObj));
        verify(departmentService, times(0)).existsByUuid(eq(departmentObj));
    }




    @Test
    public void testTwo(){
        when(employeeService.existsByUuid(uuid)).thenReturn(true);
         when(departmentService.existsByUuid(uuid)).thenReturn(true);

        create(request);

        verify(employeeService, times(1)).save(eq(empObj));
        verify(departmentService, times(1)).existsByUuid(eq(departmentObj));
    }

    @Test
    public void testThree(){
        when(employeeService.existsByUuid(uuid)).thenReturn(true);
        when(departmentService.existsByUuid(uuid)).thenReturn(false);

        assertThrows(EntityNotFoundException.class, () -> {
            create(request);
        });

        verify(employeeService, times(1)).save(eq(empObj));
        verify(departmentService, times(1)).existsByUuid(eq(departmentObj));
    }
  • Related