-
Notifications
You must be signed in to change notification settings - Fork 164
Tips and Tricks
To use the junit-dataprovider's @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 junit-dataprovider v1.10.0 and cdi-unit v3.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 {
/* ... */
}
Since v1.10.4
This is all what is required, see example integration test in package com.tngtech.test.java.junit.dataprovider.spring.
Before v1.10.4
The body of this class is identical with
DataProviderRunner.java but needs a small hack to work for version v1.10.3 and smaller. 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