I have a task where need to write alternative for TestNG @BeforeSuite using only Junit, where this extension will create test data and shared it to test class. After long research I found a good solution based on Junit API (BeforeAllCallback and ExtensionContext.Store.CloseableResource).
package org.example.firstPreconditionClassTest;
import static org.junit.jupiter.api.extension.ExtensionContext.Namespace.GLOBAL;
import lombok.*;
import org.example.StoreHelper;
import org.example.TestHelper;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
@RequiredArgsConstructor
public class BaseSetupExtension
implements BeforeAllCallback, ExtensionContext.Store.CloseableResource {
private final TestHelper testHelper;
private final StoreHelper storeHelper;
private static int a, b;
BaseSetupExtension(TestHelper testHelper) {
this.testHelper = testHelper;
this.storeHelper = new StoreHelper(testHelper);
}
@Override
public void beforeAll(ExtensionContext context) {
// We need to use a unique key here, across all usages of this particular extension.
String uniqueKey = this.getClass().getName();
Object value = context.getRoot().getStore(GLOBAL).get(uniqueKey);
if (value == null) {
// First test container invocation.
context.getRoot().getStore(GLOBAL).put(uniqueKey, this);
setup();
}
}
// Callback that is invoked <em>exactly once</em>
// before the start of <em>all</em> test containers.
public void setup() {
System.out.println("Before all test classes");
storeHelper.printSomething();
a = 111;
b = 222;
testHelper.firstMethod(a);
}
// Callback that is invoked <em>exactly once</em>
// after the end of <em>all</em> test containers.
// Inherited from {@code CloseableResource}
public void close() throws Throwable {
System.out.println("After all test classes");
}
public static int getA() {
return a;
}
public static int getB() {
return b;
}
}
It is works for initialize data like int a, b. But if I try to add helper classes (testHelper - interface, StoreHelper - class) I catch error:
org.example.firstPreconditionClassTest.BaseSetupExtension.<init>()
java.lang.NoSuchMethodException: org.example.firstPreconditionClassTest.BaseSetupExtension.<init>()
Just creating empty constructor or any variant with constructor not fixed it. In test classes there helper initialize just with lombok annotation like @RequiredArgsConstructor and its works. I don't understand why it is don't work with precondition class.
P.S. In this case main requirement: test data should be created once before test / class / suite run and will be deleted only after run finished.
Thank you for your attention! Comments with code example will be very helpful.
Builder: Gradle Java: 17 Lombok: 1.18.22 Junit: 5.8.1