Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic JUnit test class

Tags:

junit

testing

I wrote an interface MyInterface, which is going to be implemented by different implementors.

I also wrote a class MyInterfaceTest, which contains generic test methods that all implementors should be able to use to test their implementations.

I just don't know how to make it work as a JUnit test.

Currently, I have something like this:

public class MyInterfaceTest {
    private static MyInterface theImplementationToTest = null;

    @BeforeClass public static void setUpBeforeClass() throws Exception {
                // put your implementation here:
        theImplementationToTest = new Implementation(...);
    }

    @AfterClass public static void tearDownAfterClass() throws Exception { 
        theImplementationToTest = null;
    }

    @Test public void test1() { /* uses theImplementationToTest */ }    
    @Test public void test2() { /* uses theImplementationToTest */ }    
}

I use the static method setUpBeforeClass because the initialization of each implementation takes a lot of time, so I want to initialize it once for all tests.

With this version of the test, implementors have to change the code of setUpBeforeClass and put their own implementation.

I am sure that there is another way to write MyInterfaceTest, so that implementors will only have to inherit it or send it a parameter, and not change the code. However, I am not experienced enough in JUnit to make it work. Can you please show me how to do this?

like image 616
Erel Segal-Halevi Avatar asked Jul 22 '12 14:07

Erel Segal-Halevi


1 Answers

You can have the subclass implement just the before class method and inherit all the tests.

import org.junit.*;

public class ImplementingClassTest extends MyInterfaceTest {

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        // put your implementation here:
         theImplementationToTest = new MyInterfaceImpl();
    }

}

This makes the abstract class you are writing look like:

import org.junit.*;

public abstract class MyInterfaceTest {
    protected static MyInterface theImplementationToTest = null;

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
        theImplementationToTest = null;
    }

    @Test
    public void test1() { /* uses theImplementationToTest */
    }

    @Test
    public void test2() { /* uses theImplementationToTest */
    }
}

Normally, you would make the method the subclasses needed to implement abstract. Can't do that here since it is a static setup method. (In addition, you might want to refactor the instantiations to not take a long time as this is often an anti-pattern).

like image 54
Jeanne Boyarsky Avatar answered Nov 12 '22 15:11

Jeanne Boyarsky