2

The Method Under Unit Test is this.

    public void validate(PurchaseOrderRequest request)
    {
        validateBuyers(request);
        validateOrders(request);
        validateSuppliers(request);
        validateDateRange(request);
        validateStatuses(request);
    }

The Private Methods Look Like this

private void validateDateRange(PurchaseOrderRequest request)
    {
        if (request.getFromDeliveryDate() != null && request.getThruDeliveryDate() != null &&
                request.getFromDeliveryDate().isAfter(request.getThruDeliveryDate()))
        {
            throw new ValidationException(String.format(
                    "From delivery Date %s is invalid (cannot be after Thru Delivery Date of %s)",
                    request.getFromDeliveryDate(), request.getThruDeliveryDate()));
        }
    }

 private void validateBuyers(PurchaseOrderRequest request)
    {
        if (request.getBuyers() != null)
        {
            request.getBuyers().forEach(elem -> {
                validateNotNull(elem, String.format("Buyer %s is invalid", elem));
                validateRange(elem, buyerRange, String.format("Buyer %s is invalid", elem));
            });
            validateListMaxSize(request.getBuyers(), 50, "Buyers");
        }
    }

My question is, what do I need to test to ensure I get the code coverage as well as useful Unit test cases? The class under test is also a child class, and with that and the private methods, it's kind of throwing me off, or maybe I'm just over thinking it.

I currently have this:

@Test
    void validate()
    {
        RmsPurchaseOrderHeaderRequest rmsPurchaseOrderHeaderRequest = Mockito.mock(RmsPurchaseOrderHeaderRequest.class);
        RequestValidationHelper requestValidationHelper = Mockito.mock(RequestValidationHelper.class);

        requestValidationHelper.validate(rmsPurchaseOrderHeaderRequest);
        String toStringBuyers = rmsPurchaseOrderHeaderRequest.getBuyers().toString();
        String toStringOrders = rmsPurchaseOrderHeaderRequest.getOrders().toString();

        Assertions.assertNotNull(requestValidationHelper);
        Assertions.assertEquals(rmsPurchaseOrderHeaderRequest.getBuyers().toString(),toStringBuyers);
        Assertions.assertEquals(rmsPurchaseOrderHeaderRequest.getOrders().toString(),toStringOrders);

    }

but I feel like I'm way off... also if anyone knows of a good plugin to show code coverage that would be great as well. I can't get sonar lint to work.

  • Does this answer your query? [How do I test a class that has private methods, fields, or inner classes?](https://stackoverflow.com/questions/34571/how-do-i-test-a-class-that-has-private-methods-fields-or-inner-classes) – Ryednap Jan 04 '23 at 17:24
  • Your test is mocking `RequestValidationHelper` (which I assume is the class you want to test, although your question doesn't say), so you are not testing anything. There is no point asserting on the result of calling methods on mocks. – tgdavies Jan 05 '23 at 00:57

1 Answers1

1

In short: you should treat the content of the private methods as part of the public method you are testing. That means you should have test cases for each validation performed on the private methods, and you would test it by calling the public #validate method.

For instance, in one case, you would use a request with an invalid date range and assert your #validate method throws the ValidationException with the expected message. And you should create cases for each one of the cases you are validating.

Fabiano
  • 1,344
  • 9
  • 24