Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If I have multiple JUnit test classes, but they share a large amount of setup, is there a way to resuse some of this setup code?

I have a number of classes I'm testing, and I've seperated all of the tests for these classes out into their own files. i.e. I have the following sort of directory structure

  • src
    • ClassOne.java
    • ClassTwo.java
  • test
    • ClassOneTests.java
    • ClassTwoTests.java

I have a much larger number of classes to test than this however. I've started to write tests for many of these classes, and I realised that there is a lot of code in the setup that is the same between them all. I'd like to be able to reuse this code, both to reduce the time it takes to write more tests, but also in the event that I end up making modifications to my code base, I want to only have one point in the tests to change, rather than many dozens of almost identical instatiation of mocks.

An example of my code layout is like this:

public class ClassOneTests {
    //Declare global variables that are dependencies for the test
    AClass var1;
    // etc...

    ClassOne testThis;

    @Before
    public void setUp() throws Exception {
        //instantiate and populate the dependencies
        var1 = new AClass();
        // etc...

        testThis.setDependencies(var1, //And other dependencies....);
    }

    @Test
    public void aTest() {
        //Do test stuff
        Var result = testThis.doStuff();
        Assert.NotNull(result);
    }

    // etc...
}

This means a huge majority of stuff in my declaration and setUp method is duplicated across my class tests.

I have partially solved this by simply having a GenericTestSetup.java that does all of this setup and then each ClassXTest.java extends it. The problem lies with the few classes that are unique to each ClassXText.java file, but used in each method. So, in the example above AClass is a variable specific for ClassOneTests. When I do ClassTwoTests I'd have a bunch of shared variables, but then instead of AClass I'd have BClass, for example.

The problem I'm having is that I can't declare two @Before tags, one in the GenericTestClass for the generic setup, and then another in the ClassXTest class if any of the objects inside ClassXTest are dependant on something in GenericTestClass because you can't guarantee an execution order.

In summary, is there a way to have this generic test setup that's used for multiple class tests, but also have another setup method for each specific class that is guaranteed to run after the generic objects have been set up?


EDIT: It was suggested that my question is a duplicate of this question: Where to put common setUp-code for differen testclasses?

I think they're similar, but that question was asking for a more general approach in terms of policy, I have a more specific set of requirements and asking for how it would actually be implemented. Plus, none of the answers there actually gave a proper answer about implementation, which I require, so they're not useful to me.

like image 663
Seb Avatar asked Oct 18 '25 07:10

Seb


2 Answers

What i usually do when overloading increases the complexity, I use, what i call Logic classes... Basically class with static methods which takes the parameters that need to be initialized, and sets them up.

Logic.init(param1, param2)

and I usually use only one @Before with different logic methods. Advantage is that the code might be shared between similar initializations, and you can reuse the code in the Logic class itself. Example Logic.init(param1,param2,param3) can call Logic.init(param1,param2), and you can use different variants into the different @Before methods.

EDIT: I do not know if there is pattern, or a name related to such solution. If there is i would like to know the name as well :).

like image 149
Darwly Avatar answered Oct 19 '25 22:10

Darwly


You could use Template Method pattern. The @before method in the generic class calls a protected method in the same class which is empty but can be overriden in the implementing classes to add specific behaviour.

like image 43
Gualtiero Testa Avatar answered Oct 19 '25 20:10

Gualtiero Testa



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!