SonarQube doesn't recognize Mapper's unit test

552 views Asked by At

Running SonarQube Version 6.7.2 (build 37468) - LGPL v3, Junit 4 and mockito in our project, I noted that SonarQube does not recognize Mapper's unit test and decrease the project's percentual. In my local enviroment, the test works well and the coverage is 100% by Eclipse.

Below is the UT code:

@RunWith(MockitoJUnitRunner.class)
public class ClassMapperTest {
    
    @Mock
    private ClassMapper mapper;
    
    @Mock
    private ClassDTO dto;
    
    @Before
    public void setUp() {
        mapper = Mockito.mock(ClassMapper.class);
        dto = Mockito.mock(ClassDTO.class);
    }
    
    @Test
    public void returnResource() {
        Mockito.when(mapper.fromMethod(Mockito.anySet())).thenReturn(new HashSet<>());

        mapper.fromMethod(new HashSet<ClassDTO>());
    
    }

The statistics:

enter image description here

After Commit:

enter image description here

Does anyone have any idea?

1

There are 1 answers

2
Simon Schrottner On BEST ANSWER

Sonarqube is right with the computation. You do have a major issue within your test, the code you seem to be testing is mocked aka you are not testing the actual code, but a fake of it.

When you mock a class you create a dummy fake version of this class, which does not have any implementation (mapper = Mockito.mock(ClassMapper.class);). you then tell your mock to return a value when a method is called Mockito.when(mapper.fromMethod(Mockito.anySet())).thenReturn(new HashSet<>());. This way you are actually not testing your fromMethod, you just testing a method, which you told in your test what to return.

A proper test would look something like this:

@RunWith(MockitoJUnitRunner.class)
public class ClassMapperTest {
    
    private ClassMapper mapper;
    
    @Mock
    private ClassDTO dto;
    
    @Before
    public void setUp() {
        mapper = new ClassMapper();
        // no need to do that, MockitoJUnitRunner is doing this for you
        // dto = Mockito.mock(ClassDTO.class);
    }
    
    @Test
    public void returnResource() {
        // calling the actual method
        assertTrue(mapper.fromMethod(new HashSet<ClassDTO>()) != null);
    }
}

There is also no need for the dto as it is not used within your test at all, but I left it in there, to mark the unnecessary mock instantiation, which is done by the MockitoJUnitRunner.

// Disclaimer: I am not guaranteeing that your tests will pass, with my suggestion, I only want to highlight the problem with the test.