/* * Copyright 2015-2017 the original author or authors. * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License v1.0 which * accompanies this distribution and is available at * * http://www.eclipse.org/legal/epl-v10.html */ package org.junit.jupiter.engine.execution; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import java.util.Collections; import java.util.Map; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.engine.descriptor.ClassBasedContainerExtensionContext; import org.junit.jupiter.engine.descriptor.ClassTestDescriptor; import org.junit.jupiter.engine.descriptor.JupiterEngineDescriptor; import org.junit.jupiter.engine.descriptor.JupiterEngineExtensionContext; import org.junit.jupiter.engine.descriptor.MethodBasedTestExtensionContext; import org.junit.jupiter.engine.descriptor.MethodTestDescriptor; import org.junit.jupiter.engine.descriptor.NestedClassTestDescriptor; import org.junit.platform.engine.EngineExecutionListener; import org.junit.platform.engine.TestDescriptor; import org.junit.platform.engine.UniqueId; import org.junit.platform.engine.reporting.ReportEntry; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; /** * Microtests for implementors of {@linkplain ExtensionContext}: * {@linkplain JupiterEngineExtensionContext}, * {@linkplain ClassBasedContainerExtensionContext}, and * {@linkplain MethodBasedTestExtensionContext}. * * @since 5.0 * @see ExtensionValuesStoreTests */ class ExtensionContextTests { @Test void fromJupiterEngineDescriptor() { JupiterEngineDescriptor engineTestDescriptor = new JupiterEngineDescriptor( UniqueId.root("engine", "junit-jupiter")); JupiterEngineExtensionContext engineContext = new JupiterEngineExtensionContext(null, engineTestDescriptor); assertAll("engineContext", // () -> assertThat(engineContext.getTestClass()).isEmpty(), // () -> assertThat(engineContext.getTestMethod()).isEmpty(), // () -> assertThat(engineContext.getElement()).isEmpty(), // () -> assertThat(engineContext.getDisplayName()).isEqualTo(engineTestDescriptor.getDisplayName()), // () -> assertThat(engineContext.getParent()).isEmpty() // ); } @Test void fromClassTestDescriptor() { ClassTestDescriptor nestedClassDescriptor = nestedClassDescriptor(); ClassTestDescriptor outerClassDescriptor = outerClassDescriptor(nestedClassDescriptor); ClassBasedContainerExtensionContext outerExtensionContext = new ClassBasedContainerExtensionContext(null, null, outerClassDescriptor); assertAll("outerContext", // () -> assertThat(outerExtensionContext.getTestClass()).contains(OuterClass.class), // () -> assertThat(outerExtensionContext.getDisplayName()).isEqualTo(outerClassDescriptor.getDisplayName()), // () -> assertThat(outerExtensionContext.getParent()).isEmpty() // ); ClassBasedContainerExtensionContext nestedExtensionContext = new ClassBasedContainerExtensionContext( outerExtensionContext, null, nestedClassDescriptor); assertThat(nestedExtensionContext.getParent()).containsSame(outerExtensionContext); } @Test void tagsCanBeRetrievedInExtensionContext() { ClassTestDescriptor nestedClassDescriptor = nestedClassDescriptor(); ClassTestDescriptor outerClassDescriptor = outerClassDescriptor(nestedClassDescriptor); MethodTestDescriptor methodTestDescriptor = methodDescriptor(); outerClassDescriptor.addChild(methodTestDescriptor); ClassBasedContainerExtensionContext outerExtensionContext = new ClassBasedContainerExtensionContext(null, null, outerClassDescriptor); assertThat(outerExtensionContext.getTags()).containsExactly("outer-tag"); ClassBasedContainerExtensionContext nestedExtensionContext = new ClassBasedContainerExtensionContext( outerExtensionContext, null, nestedClassDescriptor); assertThat(nestedExtensionContext.getTags()).containsExactlyInAnyOrder("outer-tag", "nested-tag"); MethodBasedTestExtensionContext testExtensionContext = new MethodBasedTestExtensionContext( outerExtensionContext, null, methodTestDescriptor, new OuterClass(), new ThrowableCollector()); assertThat(testExtensionContext.getTags()).containsExactlyInAnyOrder("outer-tag", "method-tag"); } @Test void fromMethodTestDescriptor() { MethodTestDescriptor methodTestDescriptor = methodDescriptor(); ClassTestDescriptor classTestDescriptor = outerClassDescriptor(methodTestDescriptor); ClassBasedContainerExtensionContext classExtensionContext = new ClassBasedContainerExtensionContext(null, null, classTestDescriptor); MethodBasedTestExtensionContext testExtensionContext = new MethodBasedTestExtensionContext( classExtensionContext, null, methodTestDescriptor, new OuterClass(), new ThrowableCollector()); assertAll("methodContext", // () -> assertThat(testExtensionContext.getTestClass()).contains(OuterClass.class), // () -> assertThat(testExtensionContext.getDisplayName()).isEqualTo(methodTestDescriptor.getDisplayName()), // () -> assertThat(testExtensionContext.getParent()).contains(classExtensionContext), // () -> assertThat(testExtensionContext.getTestInstance()).isExactlyInstanceOf(OuterClass.class) // ); } @Test void reportEntriesArePublishedToExecutionContext() { ClassTestDescriptor classTestDescriptor = outerClassDescriptor(null); EngineExecutionListener engineExecutionListener = Mockito.spy(EngineExecutionListener.class); ExtensionContext extensionContext = new ClassBasedContainerExtensionContext(null, engineExecutionListener, classTestDescriptor); Map<String, String> map1 = Collections.singletonMap("key", "value"); Map<String, String> map2 = Collections.singletonMap("other key", "other value"); extensionContext.publishReportEntry(map1); extensionContext.publishReportEntry(map2); ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass(ReportEntry.class); Mockito.verify(engineExecutionListener, Mockito.times(2)).reportingEntryPublished( Mockito.eq(classTestDescriptor), entryCaptor.capture()); ReportEntry reportEntry1 = entryCaptor.getAllValues().get(0); ReportEntry reportEntry2 = entryCaptor.getAllValues().get(1); assertEquals(map1, reportEntry1.getKeyValuePairs()); assertEquals(map2, reportEntry2.getKeyValuePairs()); } @Test void usingStore() { MethodTestDescriptor methodTestDescriptor = methodDescriptor(); ClassTestDescriptor classTestDescriptor = outerClassDescriptor(methodTestDescriptor); ExtensionContext parentContext = new ClassBasedContainerExtensionContext(null, null, classTestDescriptor); MethodBasedTestExtensionContext childContext = new MethodBasedTestExtensionContext(parentContext, null, methodTestDescriptor, new OuterClass(), new ThrowableCollector()); ExtensionContext.Store childStore = childContext.getStore(); ExtensionContext.Store parentStore = parentContext.getStore(); final Object key1 = "key 1"; final String value1 = "a value"; childStore.put(key1, value1); assertEquals(value1, childStore.get(key1)); assertEquals(value1, childStore.remove(key1)); assertNull(childStore.get(key1)); childStore.put(key1, value1); assertEquals(value1, childStore.get(key1)); assertEquals(value1, childStore.remove(key1, String.class)); assertNull(childStore.get(key1)); final Object key2 = "key 2"; final String value2 = "other value"; assertEquals(value2, childStore.getOrComputeIfAbsent(key2, key -> value2)); assertEquals(value2, childStore.getOrComputeIfAbsent(key2, key -> value2, String.class)); assertEquals(value2, childStore.get(key2)); assertEquals(value2, childStore.get(key2, String.class)); final Object parentKey = "parent key"; final String parentValue = "parent value"; parentStore.put(parentKey, parentValue); assertEquals(parentValue, childStore.getOrComputeIfAbsent(parentKey, k -> "a different value")); assertEquals(parentValue, childStore.get(parentKey)); } private ClassTestDescriptor nestedClassDescriptor() { return new NestedClassTestDescriptor(UniqueId.root("nested-class", "NestedClass"), OuterClass.NestedClass.class); } private ClassTestDescriptor outerClassDescriptor(TestDescriptor child) { ClassTestDescriptor classTestDescriptor = new ClassTestDescriptor(UniqueId.root("class", "OuterClass"), OuterClass.class); if (child != null) classTestDescriptor.addChild(child); return classTestDescriptor; } private MethodTestDescriptor methodDescriptor() { try { return new MethodTestDescriptor(UniqueId.root("method", "aMethod"), OuterClass.class, OuterClass.class.getDeclaredMethod("aMethod")); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } } @Tag("outer-tag") static class OuterClass { @Tag("nested-tag") class NestedClass { } @Tag("method-tag") void aMethod() { } } }