Skip to content

Context of the Test is passed to the constructor when test instance is created #2961

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion documentation/src/test/java/example/TestInfoDemo.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
class TestInfoDemo {

TestInfoDemo(TestInfo testInfo) {
assertEquals("TestInfo Demo", testInfo.getDisplayName());
String displayName = testInfo.getDisplayName();
assertTrue(displayName.equals("TEST 1") || displayName.equals("test2()"));
}

@BeforeEach
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
Expand Down Expand Up @@ -274,19 +275,21 @@ private TestInstanceFactory resolveTestInstanceFactory(ExtensionRegistry registr
private TestInstancesProvider testInstancesProvider(JupiterEngineExecutionContext parentExecutionContext,
ClassExtensionContext extensionContext) {

return (registry, registrar, throwableCollector) -> extensionContext.getTestInstances().orElseGet(
() -> instantiateAndPostProcessTestInstance(parentExecutionContext, extensionContext, registry, registrar,
throwableCollector));
return (registry, registrar, throwableCollector,
clientContext) -> extensionContext.getTestInstances().orElseGet(
() -> instantiateAndPostProcessTestInstance(parentExecutionContext, extensionContext, registry,
registrar, throwableCollector, clientContext));
}

private TestInstances instantiateAndPostProcessTestInstance(JupiterEngineExecutionContext parentExecutionContext,
ExtensionContext extensionContext, ExtensionRegistry registry, ExtensionRegistrar registrar,
ThrowableCollector throwableCollector) {
ThrowableCollector throwableCollector, ExtensionContext clientContext) {

TestInstances instances = instantiateTestClass(parentExecutionContext, registry, registrar, extensionContext,
throwableCollector);
TestInstances instances = instantiateTestClass(parentExecutionContext, registry, registrar,
Objects.isNull(clientContext) ? extensionContext : clientContext, throwableCollector);
throwableCollector.execute(() -> {
invokeTestInstancePostProcessors(instances.getInnermostInstance(), registry, extensionContext);
invokeTestInstancePostProcessors(instances.getInnermostInstance(), registry,
Objects.isNull(clientContext) ? extensionContext : clientContext);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ I think we cannot simply change with which context we invoke these extension points. It's currently the container extension context for consistency with different test instance lifecycles. We could add an additional, optional context, though. 🤔

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is also an idea, but it means that one method override gets multiple contexts instead of only one.

// In addition, we register extensions from instance fields here since the
// best time to do that is immediately following test class instantiation
// and post processing.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ protected TestInstances instantiateTestClass(JupiterEngineExecutionContext paren
// Extensions registered for nested classes and below are not to be used for instantiating and initializing outer classes
ExtensionRegistry extensionRegistryForOuterInstanceCreation = parentExecutionContext.getExtensionRegistry();
TestInstances outerInstances = parentExecutionContext.getTestInstancesProvider().getTestInstances(
extensionRegistryForOuterInstanceCreation, registrar, throwableCollector);
extensionRegistryForOuterInstanceCreation, registrar, throwableCollector, null);
return instantiateTestClass(Optional.of(outerInstances), registry, extensionContext);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public JupiterEngineExecutionContext prepare(JupiterEngineExecutionContext conte
context.getExecutionListener(), this, context.getConfiguration(), throwableCollector, executableInvoker);
throwableCollector.execute(() -> {
TestInstances testInstances = context.getTestInstancesProvider().getTestInstances(registry,
throwableCollector);
throwableCollector, extensionContext);
extensionContext.setTestInstances(testInstances);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import static org.apiguardian.api.API.Status.INTERNAL;

import org.apiguardian.api.API;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.TestInstances;
import org.junit.jupiter.engine.extension.ExtensionRegistrar;
import org.junit.jupiter.engine.extension.ExtensionRegistry;
Expand All @@ -28,10 +29,15 @@ public interface TestInstancesProvider {

default TestInstances getTestInstances(MutableExtensionRegistry extensionRegistry,
ThrowableCollector throwableCollector) {
return getTestInstances(extensionRegistry, extensionRegistry, throwableCollector);
return getTestInstances(extensionRegistry, extensionRegistry, throwableCollector, null);
}

default TestInstances getTestInstances(MutableExtensionRegistry extensionRegistry,
ThrowableCollector throwableCollector, ExtensionContext context) {
return getTestInstances(extensionRegistry, extensionRegistry, throwableCollector, context);
}

TestInstances getTestInstances(ExtensionRegistry extensionRegistry, ExtensionRegistrar extensionRegistrar,
ThrowableCollector throwableCollector);
ThrowableCollector throwableCollector, ExtensionContext clientContext);

}
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ protected void assertReasonContains(String text) {
assertThat(this.result.getReason()).hasValueSatisfying(reason -> assertThat(reason).contains(text));
}

protected void assertReasonMatches(String regex) {
assertThat(this.result.getReason()).hasValueSatisfying(reason -> assertThat(reason).matches(regex));
}

protected void assertCustomDisabledReasonIs(String text) {
if (this.result.isDisabled()) {
assertThat(this.result.getReason()).hasValueSatisfying(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ protected Class<?> getTestClass() {
void enabledBecauseAnnotationIsNotPresent() {
evaluateCondition();
assertEnabled();
assertReasonContains("@DisabledIf is not present");
assertReasonMatches("(?:interface org\\.junit\\.jupiter\\.api\\.condition\\.|@)DisabledIf is not present");
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ protected Class<?> getTestClass() {
void enabledBecauseAnnotationIsNotPresent() {
evaluateCondition();
assertEnabled();
assertReasonContains("@EnabledIf is not present");
assertReasonMatches("(?:interface org\\.junit\\.jupiter\\.api\\.condition\\.|@)EnabledIf is not present");
}

/**
Expand Down