문제

I have a method like below for which I have to write the test case for FileNotFoundException

public ResponseEntity<ChefAgent> getClientDetails(String clientName) {

    LogImpl.setLogger(className,
            "Entered RESTAPI method to getClientDetails");
    ResponseEntity<ChefAgent> response = null;
    ResponseBean responseBean = null;
    ErrorBean errorBean = new ErrorBean();
    try {

        requestBean.setChefApi(ChefServiceProvider.getApi());
        requestBean.setService(NodeManagementConstants.CLIENT_DETAILS);
        requestBean.setClientName(clientName);
        responseBean = delegator.handleRequest(requestBean);

        if (null != responseBean.getChefAgent()) {
            response = new ResponseEntity<ChefAgent>(
                    responseBean.getChefAgent(), new HttpHeaders(),
                    HttpStatus.OK);
        } else {
            response = new ResponseEntity<ChefAgent>(
                    responseBean.getChefAgent(), new HttpHeaders(),
                    HttpStatus.BAD_REQUEST);
        }
        ChefServiceProvider.getClose();
    } catch (FileNotFoundException e) {
        LogImpl.setWarning(Segregator.class, e.getMessage());

        LogImpl.setWarning(className, "error occured");

        errorBean.setErrorCode(ErrorCode.FILE_NOT_FOUND_ERROR
                .getErrorCode());
        errorBean.setErrorMessage(ErrorCode.FILE_NOT_FOUND_ERROR
                .getMessage());
        ChefAgent agent = new ChefAgent();
        agent.setErrorBean(errorBean);
        response = new ResponseEntity<ChefAgent>(agent, new HttpHeaders(),
                HttpStatus.BAD_REQUEST);
        return response;
    }
    catch (CustomException e) {
        LogImpl.setWarning(Segregator.class, e.getMessage());
    }
    LogImpl.setLogger(Segregator.class,
            "Ended RESTAPI method to getClientDetails");

    return response;
}

Here the method ChefServiceProvider.getApi() have some FileInputStream operation and for which it throws FileNotFoundException. I'm not able to create a scenario in mockito where I can test the catch block in method getClientDetails(String clientName). Tried something like below

@Test()
public void testGetClientDetailsFileNotFoundException() throws Exception {

    String clientName = "client";
    ChefAgent chefAgent = new ChefAgent();
    List<ChefClientBean> chefClientBean = new ArrayList<ChefClientBean>();
    chefClientBean.add(new ChefClientBean());
    chefAgent.setChefClientList(chefClientBean);
    responseBean.setChefAgent(chefAgent);
    ResponseEntity<ChefAgent> response;

    try {
        Mockito.doThrow(new RuntimeException()).when(ChefServiceProvider.getApi());
        response = cloudManagementHelper.getClientDetails(clientName);
        Assert.assertEquals(response.getStatusCode(), HttpStatus.BAD_REQUEST);
    } catch (FileNotFoundException e) {
        System.out.println("exception");
    } 
}

But it gives error like

org.mockito.exceptions.misusing.NotAMockException: Argument passed to when() is not a mock!

Please let me know what is the correct way to do this.

I'm using below code to mock the method

PowerMockito.mockStatic(ChefServiceProvider.class);
PowerMockito.when(ChefServiceProvider.getApi()).thenReturn(chefApi);

Mockito.when(ChefServiceProvider.getApi()).thenThrow(
        new FileNotFoundException());

But then I'm getting error like

org.mockito.exceptions.misusing.MissingMethodInvocationException: when() requires an argument which has to be 'a method call on a mock'.

도움이 되었습니까?

해결책

If you're using PowerMockito:

  • You need to add annotation @PrepareForTest(ChefServiceProvider.class)
  • You need to add annotation @RunWiths(PowerMockRunner.class)
  • Then you can use: PowerMockito.mockStatic(ChefServiceProvider.class);
  • You don't need to use PowerMockito.when(ChefServiceProvider.getApi()).thenReturn(chefApi); - You can delete this line
  • You can use: PowerMockito.when(ChefServiceProvider.getApi()).thenThrow(new FileNotFoundException());

다른 팁

Have you mocked ChefServiceProvider.getApi() ? Mockito is telling you that you've not passed it a mocked object.

Native Mockito won't let you mock static methods. I would perhaps check out PowerMock for additional features allowing you to do this sort of stuff, and investigate inversion-of-control for the future to allow you to inject such dependencies.

PowerMock is a framework that extend other mock libraries such as EasyMock with more powerful capabilities. PowerMock uses a custom classloader and bytecode manipulation to enable mocking of static methods, constructors, final classes and methods, private methods, removal of static initializers and more

When I've used PowerMock I've used it to create a unit test around poorly written code, and then refactored the code to a better pattern, using PowerMock to perform regression tests. Once refactored I can then use standard Mockito practises and remove the need for PowerMock.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top