samanime
samanime

Reputation: 26527

Spring/JUnit - Run something before ANY tests

Does Spring or the JUnit runner have something that I can use to run code before running ANY tests?

The closest I've found is the @Rule and @ClassRule, which work on a class level.

I have a Docker @ClassRule which hosts an empty database for empty integration testing. With the @ClassRule, it restarts the container every time.

I'd prefer instead to just start it once when starting the tests (regardless if it's all tests or just a single one), runs the tests, then kill the container.

I've searched around, but I haven't found anything other than the class rule. Apologizes if I'm missing something obvious.

Upvotes: 2

Views: 3549

Answers (2)

A Le Dref
A Le Dref

Reputation: 452

Maybe what you are looking for are those 2 annotations :

@BeforeClass

@Before

@Before runs before each test while @BeforeClass runs only once

You can use it like this :

@Before
public void setUp(){
// start container here
}

You also have equivalent for after test : @After @AfterClass

You will find a great explanation here

Thanks

Upvotes: -1

samanime
samanime

Reputation: 26527

It appears that Spring and JUnit don't directly have anything to do this. After some more googling, I found a few bits that lead to some inspiration.

Making use of a custom rule extending ExternalResource (from JUnit), I'm kind of bastardizing it, but it does what I want:

public class MyRule extends ExternalResource {
  static private MyRule instance;

  static public MyRule get() {
    if (instance == null) {
      instance = new MyRule();
    }

    return instance;
  }

  private MyRule() {
    // do init stuff

    Runtime.getRuntime().addShutdownHook(new Thread(() -> {
      // do shutdown stuff
    });
  }
}

The basic idea is that the rule is a singleton. In each class that might need it, I'd put an @ClassRule:

 public class MyTest {
   @ClassRule
   private MyRule myRule = MyRule.get();
 }

It'll lazy-initialize itself, which will do all of the setup needed. It'll also register a shutdown hook, which will then handle any after stuff.

With this pattern, it'll run code exactly once before any tests (that need this rule) run, and it'll perform shutdown code only at the very end after all tests have finished.

Note: It purposely doesn't override the before() and after() functions, because those are before and after each class. You could add things there if you wanted to do something in between classes as well.

Upvotes: 2

Related Questions