-
Notifications
You must be signed in to change notification settings - Fork 164
Tips and Tricks
To use DataProvider in integration tests you need to extend the runners that manage the containers.
Simply copy the source code of DataProviderRunner.java into your project and rename it to something like "CdiDataProviderRunner.java" and then replace BlockJUnit4ClassRunner with CdiRunner, i.e., write
public class CdiDataProviderRunner extends CdiRunner
This was tested and works for the basic use cases with DataProvider Version 1.10.0 and cdi-unit.version 3.1.3. You are welcome to report working/non-working combinations.
To use the junit-dataprovider together with Spring integration testing, i.e. tests which have to run with the SpringJUnit4ClassRunner, you need to create a new JUnit runner similar to
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
public class DataProviderRunnerWithSpring extends SpringJUnit4ClassRunner {
/* ... */
}
The body of this class is identical with
DataProviderRunner.java but needs a small hack to work. Without any modification a NullPointerException
is thrown in
void invokeBeforeClass() {
Statement statement = new Statement() {
@Override
public void evaluate() {
// nothing to do here
}
};
statement = super.withBeforeClasses(statement);
try {
statement.evaluate();
} catch (Throwable e) {
failure = e;
}
}
The simplest solution is to comment out statement.evaluate();
, which obviously breaks the @BeforeClass
annotation. Alternatively, replacing the function above by the following two functions also fixes the issue without breaking @BeforeClass
.
void invokeBeforeClass() {
Statement statement = new Statement() {
@Override
public void evaluate() {
// nothing to do here
}
};
Statement runBeforeTestClassCallbacks = super.withBeforeClasses(statement);
// ATTENTION: This hack breaks "org.springframework.test.context.support.AbstractTestExecutionListener.beforeTestClass(TestContext)"
// as it will never be called
Statement next = getNextFromRunBeforeTestClassCallbacks(runBeforeTestClassCallbacks);
try {
next.evaluate();
} catch (Throwable e) {
failure = e;
}
}
private Statement getNextFromRunBeforeTestClassCallbacks(Statement junitBeforeClasses) {
try {
Field nextField = junitBeforeClasses.getClass().getDeclaredField("next");
nextField.setAccessible(true);
return ((Statement) nextField.get(junitBeforeClasses));
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException("Could not get 'next'-Field from 'runBeforeTestClassCallbacks' statement.", e);
}
}
This workaround results in org.springframework.test.context.support.AbstractTestExecutionListener.beforeTestClass(TestContext)
to never be called. As the default implementation of this method does not contain any operations,
this should be acceptable in most cases.
- Home
- Motivation, Distinction and FAQs
- Getting started
- Version compatibility
- Migration guides
-
Features
- Array syntax
- String syntax
- Iterable syntax
- Custom dataprovider method resolvers
- Change
@DataProvider
location - Varargs support
@BeforeClass
support (JUnit4 only)- Customize test method name
- Access
FrameworkMethod
in@DP
- Utility methods
- Convention over configuration
- Kotlin support
- OSGi compatible
MANIFEST.MF
- Tips and Tricks
- Release Notes
- Eclipse Template