简体   繁体   中英

Mockito mock a void method and throw exceptions without executing method code

I want to mock a void method that can return different kinds of exceptions. I don't want to execute the actual method. I just want to see the right codes in myResponse.

public Response myMethod(String a, String b){   
    MyResponse myresponse;
    try{
        classIWantToMock.save(a,b);
         myResponse = new MyResponse("200", SUCCESSFUL_OPERATION);
         return Response.ok(myResponse, MediaType.APPLICATION_JSON).build();
    }
    catch(NotFoundException ex){
         myResponse = new MyResponse("404", ex.getMessage());
         return Response.status(Status.NOT_FOUND).entity(myResponse).type(MediaType.APPLICATION_JSON).build();
    }
    catch(BadRequestException ex){
        myResponse = new MyResponse("400", ex.getMessage());
        return  Response.status(Status.BAD_REQUEST).entity(myResponse).type(MediaType.APPLICATION_JSON).build();
    }
    catch(Exception ex){
        myResponse = new MyResponse("500", ex.getMessage());
        return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(myResponse).type(MediaType.APPLICATION_JSON).build();
    }
}

This is not working, the test goes into the save method and causes a NullPointerException I want to avoid:

  @Test
  public void givenBadRequest_whenSaving_Then400() {
    // Given
    classIWantToMock = mock(ClassIWantToMock.class);

    // When
    doThrow(new BadRequestException("Bad Request")).when(classIWantToMock).save(isA(String.class), isA(String.class));
    response = underTest.myMethod(a, b);
    assertEquals(400, response.getStatus());
  }

TIA !

Here :

// Given
classIWantToMock = mock(ClassIWantToMock.class);

// When
doThrow(new BadRequestException("Bad Request")).when(classIWantToMock).save(isA(String.class), isA(String.class));
response = underTest.myMethod(a, b);

But mocking a class doesn't mean that all fields declared with the type of this class will be mocked.
Indeed, you mock the class that produces a mocked instance but this object is never set in the instance under test. So the NPE is expected.

ClassIWantToMock should be a dependency of the class under test. In this way you could set the mock object in it.
For example you could set it in the constructor such as :

ClassIWantToMock classIWantToMock = mock(ClassIWantToMock.class);
UnderTest underTest = new UnderTest(classIWantToMock);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM