Skip to content

Commit

Permalink
Add BlockJUnit4ClassRunner#createTest(method)
Browse files Browse the repository at this point in the history
This allows extensions of BlockJUnit4ClassRunner to provide a custom instance of the test for each FrameworkMethod invocation.

Two tests show that:

1. createTest(FrameworkMethod) can be overridden successfully
2. createTest() is called by default by createTest(FrameworkMethod)

Fixes #1036. Closes #1037.
  • Loading branch information
petergeneric authored and marcphilipp committed Dec 7, 2014
1 parent 96ca415 commit bd5b90f
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 3 deletions.
14 changes: 11 additions & 3 deletions src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -232,7 +240,7 @@ protected String testName(FrameworkMethod method) {
* Here is an outline of the default implementation:
*
* <ul>
* <li>Invoke {@code method} on the result of {@code createTest()}, and
* <li>Invoke {@code method} on the result of {@link #createTest(org.junit.runners.model.FrameworkMethod)}, and
* throw any exceptions thrown by either operation.
* <li>HOWEVER, if {@code method}'s {@code @Test} annotation has the {@code
* expecting} attribute, return normally only if the previous step threw an
Expand All @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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());
}
}

0 comments on commit bd5b90f

Please sign in to comment.