How to reuse method and test in JUnit?

Given this excerpt from your question:

… instead of the TestCaseResourceTest1 I have TestCaseResourceTest2 … I want to have a separate file for test number 2

… the standard ways of sharing code between test cases are:

  • Create a Test Suite and include the shared code in the test suite (typically in @BeforeClass and @AfterClass methods). This allows you to (1) run setup code once (per suite invocation); (2) encapsulate shared setup/teardown code and (3) easily add more tests cases later. For example:

    @RunWith(Suite.class)
    @Suite.SuiteClasses({
        TestCaseResourceTest1.class,
        TestCaseResourceTest2.class
    )}
    public class TestSuiteClass {
    
        @BeforeClass
        public void setup() {
            beforeFileTest();
        }
    
        private void beforeFileTest() throws Exception {
            // ...
        }
    }
    
  • Create an abstract class which parents TestCaseResourceTest1 and TestCaseResourceTest2 and let those test cases call the shared code in the parent (typically via super() calls). With this approach you can declare default shared code in the parent while still allowing sub classes to (1) have their own behaviour and (2) selectively override the parent/default behaviour

  • Create a custom JUnit runner, define the shared behaviour in this runner and then annotate the relevant test cases with @RunWith(YourCustomRunner.class). More details on this approach here

Just to reiterate what some of the other posters have said; this is not a common first step so you may prefer to start simple and only move to suites or abstract classes or custom runners if your usage provides a compelling reason to do so.


Assuming you want to have the exact same test run for 2 different classes (and not mocking it as in your example code), you can create an abstract test class, that has abstract method that returns an instance of the class to be tested.

Something in the vein of:

public abstract class TestCaseResourceTest {

  protected abstract TestCaseService1 getServiceToTest();

  @Before
  public void before() throws Exception {
    testCaseService1 = getServiceToTest();
    MockitoAnnotations.initMocks(this);
    beforeFileTest();
  }

  @Test
  public void test() {
    // do your test here
  }
}

public class ConcreteTest extends TestCaseResourceTest {
  protected TestCaseService1 getServiceToTest() {
    return new TestCaseService();
  }
}

public class ConcreteTest2 extends TestCaseResourceTest {
  protected TestCaseService1 getServiceToTest() {
    return new DifferentService();
  }
}

I had the such situation and it was a sign about wrong implementation design. We are talking about pure unit tests where we test exactly what is implemented in the production classes. If we need duplicated tests it means we probably have duplication in implementation.

How did I resolve it in my project?

  1. Extracted common logic into parent service class and implemented unit tests for it.
  2. For child services I implemented tests only for particular implemented code there. No more.
  3. Implemented an integration tests on real environment were both services were involved and tested completely.