Home > Back-end >  Junit test of void method
Junit test of void method

Time:01-31

I'm testing a method with a void return type, with one parameter. I'm trying to get at least some code coverage. Here's a method I'm testing:

@Service
public class VaultService {

    private final ProductRepository repository;

    private final DatabaseService databaseService;

    public VaultService(
            @Autowired BuildProperties buildProperties,
            ProductRepository repository,
            DatabaseService databaseService
    ) {
        logger.info("Creating service");

        this.repository = repository;
        this.databaseService = databaseService;
    }

    protected void checkVaultResponseErrors(VaultResponse vaultResponse) {
        if (vaultResponse.responseStatus != ResponseStatus.SUCCESS) {
            vaultResponse.errors.forEach(error -> {
                if (vaultResponse.responseStatus.equals(ResponseStatus.EXCEPTION)) {
                    throw new VaultException(error.getMessage());
                }
                if (vaultResponse.responseStatus.equals(ResponseStatus.FAILURE)) {
                    throw new VaultFailure(error.getMessage());
                }
            });
        }
    }

The VaultResponse class looks like this

@Getter
@Setter
@JsonInclude(JsonInclude.Include.NON_NULL)
public class VaultResponse {
    @JsonProperty("responseStatus")
    public ResponseStatus responseStatus;

    @JsonProperty("errors")
    public List<Error> errors;
}

And here is my test. I'm getting an error with the Mockito.verify, but the rest of the code also doesn't get any coverage. I obviously doing something wrong.

@Test
void should_check_vaultResponse_for_errors() {
    VaultService spyService = Mockito.spy(vaultService);
    VaultResponse vaultResponse = new VaultResponse();
    ResponseStatus status = ResponseStatus.SUCCESS;
    List<Error> error = new ArrayList<>();

    vaultResponse.setResponseStatus(status);
    vaultResponse.setErrors(error);

    doThrow(IllegalArgumentException.class)
            .when(spyService).checkVaultResponseErrors(vaultResponse);
    doNothing().when(spyService).checkVaultResponseErrors(vaultResponse);

    verify(spyService, times(1)).checkVaultResponseErrors(vaultResponse);
}

CodePudding user response:

Your test method clearly indicates that you want to test the checkVaultResponseErrors method. That means you should most definitely not mock it. You can mock anything needed to make it work, but not the method itself.

The way I see it, there are three tests to write:

  1. No errors:
// create VaultResponse without errors; you have that now

assertDoesNotThrow(() -> vaultService.checkVaultResponseErrors(vaultResponse));
  1. With an exception:
// create VaultResponse with status EXCEPTION

VaultException thrown = assertThrows(VaultException.class,
        () -> vaultService.checkVaultResponseErrors(vaultResponse));
// you can now assert that thrown is what you expect
  1. With a failure:
// create VaultResponse with status FAILURE

VaultFailure thrown = assertThrows(VaultFailure.class,
        () -> vaultService.checkVaultResponseErrors(vaultResponse));
// you can now assert that thrown is what you expect
  • Related