Use new features introduced in JUnit Jupiter 5.11 and 5.12

See gh-34416
This commit is contained in:
Sam Brannen 2025-02-26 15:15:15 +01:00
parent fb77fcd922
commit 5f98db6ffe
6 changed files with 137 additions and 9 deletions

View File

@ -22,6 +22,7 @@ import java.util.Objects;
import org.aopalliance.intercept.MethodInterceptor;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.IndicativeSentencesGeneration;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
@ -40,6 +41,7 @@ import static org.mockito.Mockito.mock;
* @see JdkProxyExceptionHandlingTests
* @see CglibProxyExceptionHandlingTests
*/
@IndicativeSentencesGeneration(generator = SentenceFragmentDisplayNameGenerator.class)
abstract class AbstractProxyExceptionHandlingTests {
private static final RuntimeException uncheckedException = new RuntimeException();
@ -79,6 +81,7 @@ abstract class AbstractProxyExceptionHandlingTests {
@Nested
@SentenceFragment("when there is one interceptor")
class WhenThereIsOneInterceptorTests {
private @Nullable Throwable throwableSeenByInterceptor;
@ -91,6 +94,7 @@ abstract class AbstractProxyExceptionHandlingTests {
}
@Test
@SentenceFragment("and the target throws an undeclared checked exception")
void targetThrowsUndeclaredCheckedException() throws DeclaredCheckedException {
willAnswer(sneakyThrow(undeclaredCheckedException)).given(target).doSomething();
invokeProxy();
@ -101,6 +105,7 @@ abstract class AbstractProxyExceptionHandlingTests {
}
@Test
@SentenceFragment("and the target throws a declared checked exception")
void targetThrowsDeclaredCheckedException() throws DeclaredCheckedException {
willThrow(declaredCheckedException).given(target).doSomething();
invokeProxy();
@ -109,6 +114,7 @@ abstract class AbstractProxyExceptionHandlingTests {
}
@Test
@SentenceFragment("and the target throws an unchecked exception")
void targetThrowsUncheckedException() throws DeclaredCheckedException {
willThrow(uncheckedException).given(target).doSomething();
invokeProxy();
@ -131,6 +137,7 @@ abstract class AbstractProxyExceptionHandlingTests {
@Nested
@SentenceFragment("when there are no interceptors")
class WhenThereAreNoInterceptorsTests {
@BeforeEach
@ -140,6 +147,7 @@ abstract class AbstractProxyExceptionHandlingTests {
}
@Test
@SentenceFragment("and the target throws an undeclared checked exception")
void targetThrowsUndeclaredCheckedException() throws DeclaredCheckedException {
willAnswer(sneakyThrow(undeclaredCheckedException)).given(target).doSomething();
invokeProxy();
@ -149,6 +157,7 @@ abstract class AbstractProxyExceptionHandlingTests {
}
@Test
@SentenceFragment("and the target throws a declared checked exception")
void targetThrowsDeclaredCheckedException() throws DeclaredCheckedException {
willThrow(declaredCheckedException).given(target).doSomething();
invokeProxy();
@ -156,6 +165,7 @@ abstract class AbstractProxyExceptionHandlingTests {
}
@Test
@SentenceFragment("and the target throws an unchecked exception")
void targetThrowsUncheckedException() throws DeclaredCheckedException {
willThrow(uncheckedException).given(target).doSomething();
invokeProxy();

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,6 +17,7 @@
package org.springframework.aop.framework;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.springframework.cglib.proxy.Enhancer;
@ -27,6 +28,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @since 6.2
* @see JdkProxyExceptionHandlingTests
*/
@DisplayName("CGLIB proxy exception handling")
class CglibProxyExceptionHandlingTests extends AbstractProxyExceptionHandlingTests {
@BeforeEach

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -18,6 +18,8 @@ package org.springframework.aop.framework;
import java.lang.reflect.Proxy;
import org.junit.jupiter.api.DisplayName;
import static org.assertj.core.api.Assertions.assertThat;
/**
@ -25,6 +27,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @since 6.2
* @see CglibProxyExceptionHandlingTests
*/
@DisplayName("JDK proxy exception handling")
class JdkProxyExceptionHandlingTests extends AbstractProxyExceptionHandlingTests {
@Override

View File

@ -0,0 +1,41 @@
/*
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.framework;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* {@code @SentenceFragment} is used to configure a sentence fragment for use
* with JUnit Jupiter's
* {@link org.junit.jupiter.api.DisplayNameGenerator.IndicativeSentences}
* {@code DisplayNameGenerator}.
*
* @author Sam Brannen
* @since 7.0
* @see SentenceFragmentDisplayNameGenerator
* @see org.junit.jupiter.api.DisplayName
*/
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@interface SentenceFragment {
String value();
}

View File

@ -0,0 +1,76 @@
/*
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.framework;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.util.List;
import org.junit.platform.commons.support.AnnotationSupport;
import org.junit.platform.commons.util.StringUtils;
/**
* Extension of {@link org.junit.jupiter.api.DisplayNameGenerator.Simple} that
* supports custom sentence fragments configured via
* {@link SentenceFragment @SentenceFragment}.
*
* <p>This generator can be configured for use with JUnit Jupiter's
* {@link org.junit.jupiter.api.DisplayNameGenerator.IndicativeSentences
* IndicativeSentences} {@code DisplayNameGenerator} via the
* {@link org.junit.jupiter.api.IndicativeSentencesGeneration#generator generator}
* attribute in {@code @IndicativeSentencesGeneration}.
*
* @author Sam Brannen
* @since 7.0
* @see SentenceFragment @SentenceFragment
*/
class SentenceFragmentDisplayNameGenerator extends org.junit.jupiter.api.DisplayNameGenerator.Simple {
@Override
public String generateDisplayNameForClass(Class<?> testClass) {
String sentenceFragment = getSentenceFragment(testClass);
return (sentenceFragment != null ? sentenceFragment :
super.generateDisplayNameForClass(testClass));
}
@Override
public String generateDisplayNameForNestedClass(List<Class<?>> enclosingInstanceTypes,
Class<?> nestedClass) {
String sentenceFragment = getSentenceFragment(nestedClass);
return (sentenceFragment != null ? sentenceFragment :
super.generateDisplayNameForNestedClass(enclosingInstanceTypes, nestedClass));
}
@Override
public String generateDisplayNameForMethod(List<Class<?>> enclosingInstanceTypes,
Class<?> testClass, Method testMethod) {
String sentenceFragment = getSentenceFragment(testMethod);
return (sentenceFragment != null ? sentenceFragment :
super.generateDisplayNameForMethod(enclosingInstanceTypes, testClass, testMethod));
}
private static final String getSentenceFragment(AnnotatedElement element) {
return AnnotationSupport.findAnnotation(element, SentenceFragment.class)
.map(SentenceFragment::value)
.map(String::trim)
.filter(StringUtils::isNotBlank)
.orElse(null);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -33,7 +33,7 @@ import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.assertj.core.api.AbstractAssert;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.AutoClose;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.params.ParameterizedTest;
@ -84,14 +84,10 @@ import static org.assertj.core.api.SoftAssertions.assertSoftly;
*/
class ScheduledAnnotationBeanPostProcessorTests {
@AutoClose
private final StaticApplicationContext context = new StaticApplicationContext();
@AfterEach
void closeContextAfterTest() {
context.close();
}
@ParameterizedTest
@CsvSource(textBlock = """
FixedDelay, 5_000