4

For a good portion of the tests that I do for my application I have a common setUp and tearDown.

When I create a new JUnit Test Case class I have an option for eclipse to automatically create setUp() and tearDown() methods.

Is there a way to change the default setUp and TearDown methods to have some custom lines of code?

So when I create a new test class with setUp method checked I get:

@Before
public void setUp() throws Exception
{
    UnitTestSetup.standardSetup();
}

The import shouldn't be a problem as it will automatically import the required package on save.

Aequitas
  • 2,205
  • 1
  • 25
  • 51

4 Answers4

2

If you wish to change the output of the Eclipse new JUnit Test Case wizard, that is not possible without rewriting the plugin's source code. The generated code is hard-coded into the wizard.

        buffer.append("void "); //$NON-NLS-1$
        buffer.append(methodName);
        buffer.append("() throws "); //$NON-NLS-1$
        buffer.append(imports.addImport("java.lang.Exception")); //$NON-NLS-1$
        buffer.append(" {}"); //$NON-NLS-1$
        buffer.append(delimiter);

JUnit supports inheritance. One way to apply common @Before and @After to your test cases is to put them in a common parent class, and inherit from that in your test cases:

public class Common {
     @Before
     public void setUp() {
         ...
     }
     @After
     public void tearDown() {
         ...
     }
}

public class MyTest extends Common {
    @Test
    public void test() {
        // Common.setUp() will have been run before this test
        // Common.tearDown() will run after the test
    }
}
Stuart Caie
  • 2,803
  • 14
  • 15
  • Decent answer but this would prevent me from extending MyTest from anything else. Also would mean that I would have to write extends Common every time – Aequitas Jul 28 '15 at 01:11
  • If you're writing the same code for every test case, wouldn't you want it to be defined just once, and as simple to include as `extends Common`? If you wish to change the JUnit Test Case wizard to generate different code, that's not possible unless you rewrite the plugin. – Stuart Caie Jul 28 '15 at 01:27
  • Okay thanks, that's what I wanted to know. If you include your comment in your answer, something like "it's not possible without writing a plugin, the quickest alternative would be the following..." I'll accept your answer – Aequitas Jul 28 '15 at 01:54
1

If you really see it worth it, you could write your own Annotation Processor. Then either have it process everything having @Test annotation or maybe have your own @VerySpecialTestWithGeneratedSetupAndTeardown annotation and add that to classes/methods you want to process.

It will be a whole bunch of code so you will need to have plenty of tests to justify this but here's a nice walkthrough on writing Annotation Processors: http://hannesdorfmann.com/annotation-processing/annotationprocessing101/

vertti
  • 7,539
  • 4
  • 51
  • 81
0

Why not just create a class to execute the the code to do the setup, another class to do the tear down and use those classes to encapsulate the logic required to do the set up and the tear down respectively. You could then call this logic from where ever and when ever you needed it.

Something like this:

Business class:

package com.foo.bar.businesslogic.woozinator;

public class Woozinator {

    public void doSomething() {
        System.out.println("Doing something.");
        System.out.println("Done.");
    }

}

Test class:

package com.foo.bar.businesslogic.woozinator;

import org.junit.Test;

import com.foo.bar.businesslogic.testutil.WidgitUserTestSetupUtil;
import com.foo.bar.businesslogic.testutil.WidgitUserTestTearDownUtil;

public class WoozinatorTest {

    @Test
    public void shouldPassTest() {
        WidgitUserTestSetupUtil.setUp();
        // do test stuff here
        WidgitUserTestTearDownUtil.tearDown();
    }

}

Setup class:

package com.foo.bar.businesslogic.testutil;

public class WidgitUserTestSetupUtil {

    public static void setUp() {
        System.out.println("Setting up widget environment for widget user test");
        // do stuff here
        System.out.println("Done setting up environment");
    }

}

Tear down class:

package com.foo.bar.businesslogic.testutil;

public class WidgitUserTestTearDownUtil {

    public static void tearDown() {
        System.out.println("Doing woozinator tear down.");
        // undo stuff here
        System.out.println("Done with woozinator tear down.");
    }

}
John
  • 3,458
  • 4
  • 33
  • 54
  • This is exactly what I'm doing, but I want the `WidgitUserTestSetupUtil.setUp();` and tearDown to be done automatically instead of having to write it everytime – Aequitas Jul 28 '15 at 01:13
  • You could probably do something in AspectJ or Spring AOP: http://stackoverflow.com/questions/3805317/execute-code-before-and-after-method – John Jul 28 '15 at 01:40
0

You could write a JUnit rule that extends TestWatcher and move your code to the methods starting and finished.

public class YourRule extends TestWatcher {
  @Override
  protected void starting(Description description) {
    UnitTestSetup.standardSetup();
    //more of your code
  }

  @Override
  protected void finished(Description description) {
    //your code
  }
}

Use this rule in every test:

public class YourTest {
  @Rule
  public final YourRule yourRule = new YourRule();

  ...
}
Stefan Birkner
  • 24,059
  • 12
  • 57
  • 72