6

When testing, sometimes a helper method can be useful for repeated task e.g. in test setup.

Concrete example: We have certain tests against our rest interface using Spring's RestTemplate. To make it easier, the requests are sent with the help of a helper method (let's call it method A() for now), which returns the objects from the response.

This helper method A() seems to pollute the test class, as it is a method which is actually not a test itself. Having multiple helper methods in a test class has a negative effect regarding the overview.

Is it acceptable to create a second class next to the test class, which is containing all helper method? What would be the difficulties if doing so? Or are there any other ways to keep a good overview of the test class?

  • MyTestClass -> containing only methods which are a actuall test
  • MyTestClassUtil -> containing all helper methods that are used by MyTestClass
  • wait.. explain the test again? don't you have a client to go with the api which you can run the tests against? – Ewan Aug 22 '17 at 10:03
  • @Ewan It's an integration test in this case. The spring test suite will run the server implementation to test and the RestTemplate is simulating a client. Although I think this shouldn't really matter. The main issue is, that there is a helper method which is used by multiple tests. – Herr Derb Aug 22 '17 at 10:10
  • Yes that is acceptable. It's hard to think of any difficulties, beyond your choice of name. MyTestClassUtil doesn't really tell me what that class is for. MyTestClassCommonSetup or some such would seem a better name. – David Arno Aug 22 '17 at 10:49
  • I use to solve this with inheritance. Whether this good or bad, I only can say is that it works for me. Common methods and utilities of Integration-Tests are implemented in a superclass (abstract). Often I also use It for templating tests, initialize the tests framework, prepare settings, etc. It could be done with composition too, but I feel myself like implementing an API for tests over another API for test (Spring tests, JUnit, etc). – Laiv Aug 22 '17 at 10:50
  • it sounds like your helpermethod IS the client? I would expect you to already have a MyApiClient class for each Api, you would then create integration tests of your Api using this client. – Ewan Aug 22 '17 at 11:21
9

Is it acceptable to create a second class next to the test class, which is containing all helper method?

Not with all helper methods, but with helper methods that are used in more than one test class.

Design your tests the same way as you implement business classes!

Refactor code duplicates within a class into a local method. If the method is used in different test classes move it into a different test helper class that is used by different tests.

So my OrderTests class has a local method assertEqual(String message, IOrder expected, IOrder actual) and my helper TestDataFactory has a static method createTestOrder() that is used in OrderTests, PriceCalculationTests, PaymentTests, DeliveryTests.

A test may use one or more of the standard factory methods and modifies it as needed. Example:

DeliveryTests.executeOrderWithNoDeliveryAdressShouldThrow() {
    // a valid standard order with one article, user, deliveryadress, ...
    Order sut = TestDataFactory.createTestOrder(); 
    sut.setDeliveryAdress(null); // implements "WithNoDeliveryAdress"

    try {
        sut.execute(); // this should throw
        Assert.fail(); // this should never be reached because of exception.
    } catch(OrderNotCompleteException) {
    }
}
2

According to Michael C. Feathers in Working Effectively with Legacy Code You can create what he called an Object Seam; A class implementing the interface you are testing, or inheriting from the class you are testing. in this case, you do not contaminate your original code with unit testing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.