ITMan
ITMan

Reputation: 11

Using Mockito Spy

I tried to write a Junit test case for below service class of Spring Boot app.

@Service
@Transactional
public class MyService {
    private static final Logger log = LoggerFactory.getLogger(ataService.class);

    @Autowire
    private MyRepository myRepo;

    public Map<String, Object> myMethod(Response rsp, Request req) {
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("PROCESS_I", req.getProcessI());
        data.put("REQUEST_I", req.getRequestI());
        data.put("TYPE_COE", req.getTypeCoe());
        data.put("STATUS_COE", rsp.getStatusCoe());
        
        Map<String, Object> result = null;
        try {
            result = myRepo.update(ata);
        } catch (Exception e) {
            log.error("Error occurre uring upate : " + e.getMessage());
        }   

        return result;
    }
}

I tried to cover as many lines as possible with this test case

@RunWith(MockitoJUnitRunner.class)
public class MyServiceTest {
    
    @Mock
    private MyRepository myRepository;
    
    @Spy
    private MyService  myService;

    @Test
    public voi test() {
        Request req = new Request();
        req.setProcessI(new Bigecimal("43850"));
        req.setRequestI(new Bigecimal("146717"));
        req.setTypeCoe("ABC");
        
        Response rsp = new Response();
        vetResp.setStatusCoe("N");

        Map<String, Object> data = new HashMap<String, Object>();
        data.put("PROCESS_I", req.getProcessI());
        data.put("REQUEST_I", req.getRequestI());
        data.put("TYPE_COE", req.getTypeCoe());
        data.put("STATUS_COE", rsp.getStatusCoe());
        
        Map<String, Object> result = null;
        try {
            doReturn(result).when(myRepository.update(data));
            result = myService.myMethod(vetResp, req);
            verify(myRepository, atLeast(1)).update(any(Map.class));
        } catch(Exception e) {
        }
    }
}

I thought the statement "myService.myMethod(vetResp, req);" will run the real method since myService is annotated with @Spy. But the SonarQube scan report shows that no single line of the method is covered.

I am new to Mockito. Could anyone show me what I did wrong? Thanks!

Thank you all for your inputs. I replaced @Spy with @InjectMocks, but it doesn't increase code coverage at all. I need mock MyRepository so I don't have to set up datasource/connection. Could anyone show sample test code that can cover most lines of tested code?

Upvotes: 0

Views: 688

Answers (1)

Dawood ibn Kareem
Dawood ibn Kareem

Reputation: 79848

You've got three main problems with this test.

  • You're using a Spy, for no reason at all. You're not using any Spy features, so you shouldn't bother. Just use a real MyService object and test that.
  • You haven't injected your mock MyRepository at all. That means that the mock will never receive the calls that your class makes on the myRepo reference. There are a few different ways you could fix that, but the simplest one is probably to put an @InjectMocks annotation on the MyService declaration in your test.
  • Your test has a try/catch block, where you throw away any exceptions. This means that if something goes wrong in your test, you'll never find out about it. Remove the try/catch and let JUnit report any exceptions, so that you actually see them.

Upvotes: 2

Related Questions