OiO.lk Blog java @Spy with @InjectMocks in Mockito
java

@Spy with @InjectMocks in Mockito


I am trying to write unit test for my ProjectsService class. the class depends on ProjectsRepository. So I annotated the repository with @Mock to avoid calling real database and annotate the projectsService with @InjectMocks to inject the required dependencies. Moreover, I want to test some methods in the projects service not all of them. I want to test the assignSharedProjects() method and to mock the call and result of the getSharedProjects(). Below is the test method and the actual method:

@SpringBootTest
public class SharedProjectsServiceTest {

    @InjectMocks
    @Spy
    ProjectsService projectsService;

    @Mock
    ProjectsRepository projectsRepository;


    @BeforeEach
    void setUp() throws ApiException {
        tokenInfo = new TokenInfo();
        tokenInfo.setUserName("john doe");

        ProjectsEntity mockBenefitProject = new ProjectsEntity();
        mockBenefitProject.setPrjId(70L);

        ProjectsEntity mockBenefitProject2 = new ProjectsEntity();
        mockBenefitProject2.setPrjId(87L);

        SharedProjectsEntity shr1 = new SharedProjectsEntity();
        shr1.setId(new SharedProjectsId(90L, 70L));
        shr1.setBenefitingProject(mockBenefitProject);
        shr1.setSharedPercentage(50.0);

        ProjectsEntity mockOriginalProject = new ProjectsEntity();
        mockOriginalProject.setPrjId(90L);
        mockOriginalProject.setSharedProjects(List.of(shr1));

        when(projectsRepository.findByPrjId(90L)).thenReturn(mockOriginalProject);
        when(projectsRepository.findByPrjId(70L)).thenReturn(mockBenefitProject);
        when(projectsRepository.findByPrjId(87L)).thenReturn(mockBenefitProject2);
}

    @Test
    void testingAssignProjectsToSharedProject() throws ApiException {
        doThrow(RuntimeException.class).when(projectsService).getSharedProjects(tokenInfo,90L, 1, 10, "benefitingProjectName", "asc",null);
        doCallRealMethod().when(projectsService).assignSharedProjects(tokenInfo, 90L, Map.of(87L, 40.0, 70L, 20.0),1,10,"benefitingProjectName","asc");
        Object result = projectsService.assignSharedProjects(tokenInfo, 90L, Map.of(87L, 40.0, 70L, 20.0), 1, 10, "benefitingProjectName", "asc");

assertEquals("Total Shared Percentage Exceeds 100", result);

}

//The actual method is the ProjectsService Class: 

 public Object assignSharedProjects(TokenInfo tokenInfo, Long OriginalProjectId, Map<Long,Double> sharedProjectsId, int page, int rows,String attr, String sortBy ) throws ApiException{
        ProjectsEntity originalProject = projectsRepository.findByPrjId(OriginalProjectId);
        if(originalProject == null) {
            throw ExceptionConstants.PROJECT_NOT_EXISTS;
        }
        Map<Long, Double> testSharedProjectsId = new HashMap<>(sharedProjectsId);
        double[] sharedPercentage = {0};
        originalProject.getSharedProjects().forEach((c)->{
            if(sharedProjectsId.containsKey(c.getBenefitingProject().getPrjId())){
                sharedPercentage[0] += testSharedProjectsId.get(c.getBenefitingProject().getPrjId());
                testSharedProjectsId.remove(c.getBenefitingProject().getPrjId());
            }else{
                sharedPercentage[0] += c.getSharedPercentage();
            }
        });

        if (sharedPercentage[0]>100){
            return new String("Total Shared Percentage Exceeds 100");
        }

        for(Long id: testSharedProjectsId.keySet()){
            sharedPercentage[0] += testSharedProjectsId.get(id);
            if (sharedPercentage[0]>100){
                return new String("Total Shared Percentage Exceeds 100");
            }
        }

        for(Long sharedProjectId: sharedProjectsId.keySet()){
            ProjectsEntity benefitingProject = projectsRepository.findByPrjId(sharedProjectId);
            if(benefitingProject == null) {
                throw ExceptionConstants.PROJECT_NOT_EXISTS;
            }

            SharedProjectsId id = new SharedProjectsId();
            id.setSharedProjectId(OriginalProjectId);
            id.setBenefitingProjectId(sharedProjectId);

            SharedProjectsEntity sharedProjectsEntity = new SharedProjectsEntity();
            sharedProjectsEntity.setId(id);
            sharedProjectsEntity.setProject(originalProject);
            sharedProjectsEntity.setBenefitingProject(benefitingProject);
            sharedProjectsEntity.setBenefitingProjectName(benefitingProject.getPrjName());
            sharedProjectsEntity.setSharedPercentage(sharedProjectsId.get(sharedProjectId));
            sharedProjectsEntity.setSharedCreatedBy(tokenInfo.getUserName());
            sharedProjectsEntity.setSharedCreatedOn(currentTime());
            sharedProjectsEntity.setSharedUpdatedBy(tokenInfo.getUserName());
            sharedProjectsEntity.setSharedUpdatedOn(currentTime());
            sharedProjectsEntity.setClientName(tokenInfo.getClientName());
            sharedProjectsRepository.save(sharedProjectsEntity);
        }
        return getSharedProjects(tokenInfo,OriginalProjectId, page,  rows, attr,  sortBy ,null);
    } // assign shared projects to original project

I expect to execute the assignSharedProjects method and to reach the return new String("Total Shared Percentage Exceeds 100") statement so the assertEquals satisfies. But the actual result is the RunTimeException is thrown, and the method is not executed with the mocked dependencies when I debug it also the method parameters is not passed, and the debugging parameters are projectsRepository this is not available.

I tried to remove the @Spy from the service and use

when(projectsService.getSharedProjects(tokenInfo,90L, 1, 10, "benefitingProjectName", "asc",null)).thenThrow(RuntimeException.class);

but it does not work also. The call of projectsService.getSharedProjects is not skipped.
Can you assist on this problem or advise another approach. I want to discard and not call the real method projectsService.getSharedProjects , just to test the assignSaredProjects method?



You need to sign in to view this answers

Exit mobile version