diff --git a/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java b/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java
index 4d06199164e8..f9b418911fad 100644
--- a/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java
+++ b/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java
@@ -217,6 +217,14 @@ protected Object createTest() throws Exception {
return getTestClass().getOnlyConstructor().newInstance();
}
+ /**
+ * Returns a new fixture to run a particular test {@code method} against.
+ * Default implementation executes the no-argument {@link #createTest()} method.
+ */
+ protected Object createTest(FrameworkMethod method) throws Exception {
+ return createTest();
+ }
+
/**
* Returns the name that describes {@code method} for {@link Description}s.
* Default implementation is the method's name
@@ -232,7 +240,7 @@ protected String testName(FrameworkMethod method) {
* Here is an outline of the default implementation:
*
*
- * - Invoke {@code method} on the result of {@code createTest()}, and
+ *
- Invoke {@code method} on the result of {@link #createTest(org.junit.runners.model.FrameworkMethod)}, and
* throw any exceptions thrown by either operation.
*
- HOWEVER, if {@code method}'s {@code @Test} annotation has the {@code
* expecting} attribute, return normally only if the previous step threw an
@@ -257,13 +265,13 @@ protected String testName(FrameworkMethod method) {
* This can be overridden in subclasses, either by overriding this method,
* or the implementations creating each sub-statement.
*/
- protected Statement methodBlock(FrameworkMethod method) {
+ protected Statement methodBlock(final FrameworkMethod method) {
Object test;
try {
test = new ReflectiveCallable() {
@Override
protected Object runReflectiveCall() throws Throwable {
- return createTest();
+ return createTest(method);
}
}.run();
} catch (Throwable e) {
diff --git a/src/test/java/org/junit/tests/experimental/rules/BlockJUnit4ClassRunnerOverrideTest.java b/src/test/java/org/junit/tests/experimental/rules/BlockJUnit4ClassRunnerOverrideTest.java
index 5a6274813ae3..9dd0f719969e 100644
--- a/src/test/java/org/junit/tests/experimental/rules/BlockJUnit4ClassRunnerOverrideTest.java
+++ b/src/test/java/org/junit/tests/experimental/rules/BlockJUnit4ClassRunnerOverrideTest.java
@@ -2,6 +2,7 @@
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
import static org.junit.experimental.results.PrintableResult.testResult;
import static org.junit.experimental.results.ResultMatchers.isSuccessful;
@@ -89,4 +90,88 @@ public static class OverrideTestRulesTest extends OverrideRulesTest {
public void overrideTestRulesMethod() {
assertThat(testResult(OverrideRulesTest.class), isSuccessful());
}
+
+
+ /**
+ * Runner for testing override of {@link org.junit.runners.BlockJUnit4ClassRunner#createTest(org.junit.runners.model.FrameworkMethod)}
+ * by setting the {@link org.junit.runners.model.FrameworkMethod} in a field
+ * of the test class so it can be compared with the test method that is being
+ * executed.
+ */
+ public static class OverrideCreateTestRunner extends BlockJUnit4ClassRunner {
+ public OverrideCreateTestRunner(final Class> klass) throws InitializationError {
+ super(klass);
+
+ assert(klass.equals(OverrideCreateTest.class));
+ }
+
+ @Override
+ protected Object createTest(FrameworkMethod method) {
+ final OverrideCreateTest obj = new OverrideCreateTest();
+
+ obj.method = method;
+
+ return obj;
+ }
+ }
+
+ @RunWith(OverrideCreateTestRunner.class)
+ public static class OverrideCreateTest {
+ public FrameworkMethod method;
+
+ @Test
+ public void testMethodA() {
+ assertEquals("testMethodA", method.getMethod().getName());
+ }
+
+ @Test
+ public void testMethodB() {
+ assertEquals("testMethodB", method.getMethod().getName());
+ }
+ }
+
+ @Test
+ public void overrideCreateTestMethod() {
+ assertThat(testResult(OverrideCreateTest.class), isSuccessful());
+ }
+
+
+ /**
+ * Runner for testing override of {@link org.junit.runners.BlockJUnit4ClassRunner#createTest()}
+ * is still called by default if no other {@code createTest} method override
+ * is in place. This is tested by setting a boolean flag in a field of the
+ * test class so it can be checked to confirm that the createTest method was
+ * called.
+ */
+ public static class CreateTestDefersToNoArgCreateTestRunner extends BlockJUnit4ClassRunner {
+ public CreateTestDefersToNoArgCreateTestRunner(final Class> klass) throws InitializationError {
+ super(klass);
+
+ assert(klass.equals(CreateTestDefersToNoArgCreateTestTest.class));
+ }
+
+ @Override
+ protected Object createTest() {
+ final CreateTestDefersToNoArgCreateTestTest obj = new CreateTestDefersToNoArgCreateTestTest();
+
+ obj.createTestCalled = true;
+
+ return obj;
+ }
+ }
+
+ @RunWith(CreateTestDefersToNoArgCreateTestRunner.class)
+ public static class CreateTestDefersToNoArgCreateTestTest {
+ public boolean createTestCalled = false;
+
+ @Test
+ public void testCreateTestCalled() {
+ assertEquals(true, createTestCalled);
+ }
+ }
+
+ @Test
+ public void createTestDefersToNoArgCreateTest() {
+ assertThat(testResult(CreateTestDefersToNoArgCreateTestTest.class), isSuccessful());
+ }
}