Polishing

This commit is contained in:
Sam Brannen
2024-03-12 17:34:02 +01:00
parent 3b87c87a33
commit 7211db9262
8 changed files with 173 additions and 178 deletions

View File

@@ -29,12 +29,35 @@ import org.springframework.lang.Nullable;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link OverrideMetadata}.
*
* @author Simon Baslé
* @since 6.2
*/
class OverrideMetadataTests {
@Test
void implicitConfigurations() throws Exception {
OverrideMetadata metadata = exampleOverride();
assertThat(metadata.getExpectedBeanName()).as("expectedBeanName").isEqualTo(metadata.field().getName());
}
@NonNull
String annotated = "exampleField";
private static OverrideMetadata exampleOverride() throws Exception {
Field field = OverrideMetadataTests.class.getDeclaredField("annotated");
return new ConcreteOverrideMetadata(Objects.requireNonNull(field), field.getAnnotation(NonNull.class),
ResolvableType.forClass(String.class), BeanOverrideStrategy.REPLACE_DEFINITION);
}
static class ConcreteOverrideMetadata extends OverrideMetadata {
ConcreteOverrideMetadata(Field field, Annotation overrideAnnotation, ResolvableType typeToOverride,
BeanOverrideStrategy strategy) {
super(field, overrideAnnotation, typeToOverride, strategy);
}
@@ -44,25 +67,11 @@ class OverrideMetadataTests {
}
@Override
protected Object createOverride(String beanName, @Nullable BeanDefinition existingBeanDefinition, @Nullable Object existingBeanInstance) {
protected Object createOverride(String beanName, @Nullable BeanDefinition existingBeanDefinition,
@Nullable Object existingBeanInstance) {
return BeanOverrideStrategy.REPLACE_DEFINITION;
}
}
@NonNull
public String annotated = "exampleField";
static OverrideMetadata exampleOverride() throws NoSuchFieldException {
final Field annotated = OverrideMetadataTests.class.getField("annotated");
return new ConcreteOverrideMetadata(Objects.requireNonNull(annotated), annotated.getAnnotation(NonNull.class),
ResolvableType.forClass(String.class), BeanOverrideStrategy.REPLACE_DEFINITION);
}
@Test
void implicitConfigurations() throws NoSuchFieldException {
final OverrideMetadata metadata = exampleOverride();
assertThat(metadata.getExpectedBeanName()).as("expectedBeanName")
.isEqualTo(metadata.field().getName());
}
}

View File

@@ -24,78 +24,85 @@ import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Bean;
import org.springframework.core.ResolvableType;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.test.context.bean.override.convention.TestBeanOverrideProcessor.MethodConventionOverrideMetadata;
import org.springframework.test.context.bean.override.example.ExampleService;
import org.springframework.test.context.bean.override.example.FailingExampleService;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatException;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
/**
* Tests for {@link TestBeanOverrideProcessor}.
*
* @author Simon Baslé
* @since 6.2
*/
class TestBeanOverrideProcessorTests {
@Test
void ensureMethodFindsFromList() {
Method m = TestBeanOverrideProcessor.ensureMethod(MethodConventionConf.class, ExampleService.class,
Method method = TestBeanOverrideProcessor.ensureMethod(MethodConventionConf.class, ExampleService.class,
"example1", "example2", "example3");
assertThat(m.getName()).isEqualTo("example2");
assertThat(method.getName()).isEqualTo("example2");
}
@Test
void ensureMethodNotFound() {
assertThatException().isThrownBy(() -> TestBeanOverrideProcessor.ensureMethod(
MethodConventionConf.class, ExampleService.class, "example1", "example3"))
assertThatIllegalStateException()
.isThrownBy(() -> TestBeanOverrideProcessor.ensureMethod(MethodConventionConf.class, ExampleService.class,
"example1", "example3"))
.withMessage("Found 0 static methods instead of exactly one, matching a name in [example1, example3] with return type " +
ExampleService.class.getName() + " on class " + MethodConventionConf.class.getName())
.isInstanceOf(IllegalStateException.class);
ExampleService.class.getName() + " on class " + MethodConventionConf.class.getName());
}
@Test
void ensureMethodTwoFound() {
assertThatException().isThrownBy(() -> TestBeanOverrideProcessor.ensureMethod(
MethodConventionConf.class, ExampleService.class, "example2", "example4"))
assertThatIllegalStateException()
.isThrownBy(() -> TestBeanOverrideProcessor.ensureMethod(MethodConventionConf.class, ExampleService.class,
"example2", "example4"))
.withMessage("Found 2 static methods instead of exactly one, matching a name in [example2, example4] with return type " +
ExampleService.class.getName() + " on class " + MethodConventionConf.class.getName())
.isInstanceOf(IllegalStateException.class);
ExampleService.class.getName() + " on class " + MethodConventionConf.class.getName());
}
@Test
void ensureMethodNoNameProvided() {
assertThatException().isThrownBy(() -> TestBeanOverrideProcessor.ensureMethod(
MethodConventionConf.class, ExampleService.class))
.withMessage("At least one expectedMethodName is required")
.isInstanceOf(IllegalArgumentException.class);
assertThatIllegalArgumentException()
.isThrownBy(() -> TestBeanOverrideProcessor.ensureMethod(MethodConventionConf.class, ExampleService.class))
.withMessage("At least one expectedMethodName is required");
}
@Test
void createMetaDataForUnknownExplicitMethod() throws NoSuchFieldException {
Field f = ExplicitMethodNameConf.class.getField("a");
final TestBean overrideAnnotation = Objects.requireNonNull(AnnotationUtils.getAnnotation(f, TestBean.class));
Field field = ExplicitMethodNameConf.class.getField("a");
TestBean overrideAnnotation = Objects.requireNonNull(field.getAnnotation(TestBean.class));
TestBeanOverrideProcessor processor = new TestBeanOverrideProcessor();
assertThatException().isThrownBy(() -> processor.createMetadata(f, overrideAnnotation, ResolvableType.forClass(ExampleService.class)))
assertThatIllegalStateException()
.isThrownBy(() -> processor.createMetadata(field, overrideAnnotation, ResolvableType.forClass(ExampleService.class)))
.withMessage("Found 0 static methods instead of exactly one, matching a name in [explicit1] with return type " +
ExampleService.class.getName() + " on class " + ExplicitMethodNameConf.class.getName())
.isInstanceOf(IllegalStateException.class);
ExampleService.class.getName() + " on class " + ExplicitMethodNameConf.class.getName());
}
@Test
void createMetaDataForKnownExplicitMethod() throws NoSuchFieldException {
Field f = ExplicitMethodNameConf.class.getField("b");
final TestBean overrideAnnotation = Objects.requireNonNull(AnnotationUtils.getAnnotation(f, TestBean.class));
Field field = ExplicitMethodNameConf.class.getField("b");
TestBean overrideAnnotation = Objects.requireNonNull(field.getAnnotation(TestBean.class));
TestBeanOverrideProcessor processor = new TestBeanOverrideProcessor();
assertThat(processor.createMetadata(f, overrideAnnotation, ResolvableType.forClass(ExampleService.class)))
.isInstanceOf(TestBeanOverrideProcessor.MethodConventionOverrideMetadata.class);
assertThat(processor.createMetadata(field, overrideAnnotation, ResolvableType.forClass(ExampleService.class)))
.isInstanceOf(MethodConventionOverrideMetadata.class);
}
@Test
void createMetaDataWithDeferredEnsureMethodCheck() throws NoSuchFieldException {
Field f = MethodConventionConf.class.getField("field");
final TestBean overrideAnnotation = Objects.requireNonNull(AnnotationUtils.getAnnotation(f, TestBean.class));
Field field = MethodConventionConf.class.getField("field");
TestBean overrideAnnotation = Objects.requireNonNull(field.getAnnotation(TestBean.class));
TestBeanOverrideProcessor processor = new TestBeanOverrideProcessor();
assertThat(processor.createMetadata(f, overrideAnnotation, ResolvableType.forClass(ExampleService.class)))
.isInstanceOf(TestBeanOverrideProcessor.MethodConventionOverrideMetadata.class);
assertThat(processor.createMetadata(field, overrideAnnotation, ResolvableType.forClass(ExampleService.class)))
.isInstanceOf(MethodConventionOverrideMetadata.class);
}
static class MethodConventionConf {
@TestBean
@@ -127,4 +134,5 @@ class TestBeanOverrideProcessorTests {
return new FailingExampleService();
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
@@ -35,9 +35,7 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.WebRequest;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.fail;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItems;
@@ -53,10 +51,7 @@ import static org.springframework.http.HttpHeaders.VARY;
*
* @author Rossen Stoyanchev
*/
public class HeaderAssertionTests {
private static final String ERROR_MESSAGE = "Should have thrown an AssertionError";
class HeaderAssertionTests {
private String now;
@@ -70,7 +65,7 @@ public class HeaderAssertionTests {
@BeforeEach
public void setup() {
void setup() {
this.dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
this.dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
this.now = dateFormat.format(new Date(this.currentTime));
@@ -83,7 +78,7 @@ public class HeaderAssertionTests {
@Test
public void stringWithCorrectResponseHeaderValue() {
void stringWithCorrectResponseHeaderValue() {
testClient.get().uri("/persons/1").header(IF_MODIFIED_SINCE, minuteAgo)
.exchange()
.expectStatus().isOk()
@@ -91,7 +86,7 @@ public class HeaderAssertionTests {
}
@Test
public void stringWithMatcherAndCorrectResponseHeaderValue() {
void stringWithMatcherAndCorrectResponseHeaderValue() {
testClient.get().uri("/persons/1").header(IF_MODIFIED_SINCE, minuteAgo)
.exchange()
.expectStatus().isOk()
@@ -99,7 +94,7 @@ public class HeaderAssertionTests {
}
@Test
public void multiStringHeaderValue() {
void multiStringHeaderValue() {
testClient.get().uri("/persons/1")
.exchange()
.expectStatus().isOk()
@@ -107,7 +102,7 @@ public class HeaderAssertionTests {
}
@Test
public void multiStringHeaderValueWithMatchers() {
void multiStringHeaderValueWithMatchers() {
testClient.get().uri("/persons/1")
.exchange()
.expectStatus().isOk()
@@ -115,7 +110,7 @@ public class HeaderAssertionTests {
}
@Test
public void dateValueWithCorrectResponseHeaderValue() {
void dateValueWithCorrectResponseHeaderValue() {
testClient.get().uri("/persons/1")
.header(IF_MODIFIED_SINCE, minuteAgo)
.exchange()
@@ -124,7 +119,7 @@ public class HeaderAssertionTests {
}
@Test
public void longValueWithCorrectResponseHeaderValue() {
void longValueWithCorrectResponseHeaderValue() {
testClient.get().uri("/persons/1")
.exchange()
.expectStatus().isOk()
@@ -132,7 +127,7 @@ public class HeaderAssertionTests {
}
@Test
public void stringWithMissingResponseHeader() {
void stringWithMissingResponseHeader() {
testClient.get().uri("/persons/1")
.header(IF_MODIFIED_SINCE, now)
.exchange()
@@ -141,7 +136,7 @@ public class HeaderAssertionTests {
}
@Test
public void stringWithMatcherAndMissingResponseHeader() {
void stringWithMatcherAndMissingResponseHeader() {
testClient.get().uri("/persons/1").header(IF_MODIFIED_SINCE, now)
.exchange()
.expectStatus().isNotModified()
@@ -149,25 +144,18 @@ public class HeaderAssertionTests {
}
@Test
public void longValueWithMissingResponseHeader() {
try {
testClient.get().uri("/persons/1").header(IF_MODIFIED_SINCE, now)
.exchange()
.expectStatus().isNotModified()
.expectHeader().valueEquals("X-Custom-Header", 99L);
fail(ERROR_MESSAGE);
}
catch (AssertionError err) {
if (ERROR_MESSAGE.equals(err.getMessage())) {
throw err;
}
assertThat(err.getMessage()).startsWith("Response does not contain header 'X-Custom-Header'");
}
void longValueWithMissingResponseHeader() {
String headerName = "X-Custom-Header";
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
testClient.get().uri("/persons/1").header(IF_MODIFIED_SINCE, now)
.exchange()
.expectStatus().isNotModified()
.expectHeader().valueEquals(headerName, 99L))
.withMessage("Response does not contain header '%s'", headerName);
}
@Test
public void exists() {
void exists() {
testClient.get().uri("/persons/1")
.exchange()
.expectStatus().isOk()
@@ -175,7 +163,7 @@ public class HeaderAssertionTests {
}
@Test
public void existsFail() {
void existsFail() {
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
testClient.get().uri("/persons/1")
.exchange()
@@ -184,7 +172,7 @@ public class HeaderAssertionTests {
}
@Test
public void doesNotExist() {
void doesNotExist() {
testClient.get().uri("/persons/1")
.exchange()
.expectStatus().isOk()
@@ -192,7 +180,7 @@ public class HeaderAssertionTests {
}
@Test
public void doesNotExistFail() {
void doesNotExistFail() {
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
testClient.get().uri("/persons/1")
.exchange()
@@ -201,7 +189,7 @@ public class HeaderAssertionTests {
}
@Test
public void longValueWithIncorrectResponseHeaderValue() {
void longValueWithIncorrectResponseHeaderValue() {
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
testClient.get().uri("/persons/1")
.exchange()
@@ -210,7 +198,7 @@ public class HeaderAssertionTests {
}
@Test
public void stringWithMatcherAndIncorrectResponseHeaderValue() {
void stringWithMatcherAndIncorrectResponseHeaderValue() {
long secondLater = this.currentTime + 1000;
String expected = this.dateFormat.format(new Date(secondLater));
assertIncorrectResponseHeader(spec -> spec.expectHeader().valueEquals(LAST_MODIFIED, expected), expected);
@@ -222,30 +210,13 @@ public class HeaderAssertionTests {
}
private void assertIncorrectResponseHeader(Consumer<WebTestClient.ResponseSpec> assertions, String expected) {
try {
WebTestClient.ResponseSpec spec = testClient.get().uri("/persons/1")
.header(IF_MODIFIED_SINCE, minuteAgo)
.exchange()
.expectStatus().isOk();
assertions.accept(spec);
fail(ERROR_MESSAGE);
}
catch (AssertionError err) {
if (ERROR_MESSAGE.equals(err.getMessage())) {
throw err;
}
assertMessageContains(err, "Response header '" + LAST_MODIFIED + "'");
assertMessageContains(err, expected);
assertMessageContains(err, this.now);
}
}
private void assertMessageContains(AssertionError error, String expected) {
assertThat(error.getMessage())
.as("Failure message should contain [" + expected + "], actual is [" + error.getMessage() + "]")
.contains(expected);
WebTestClient.ResponseSpec spec = testClient.get().uri("/persons/1")
.header(IF_MODIFIED_SINCE, minuteAgo)
.exchange()
.expectStatus().isOk();
assertThatExceptionOfType(AssertionError.class)
.isThrownBy(() -> assertions.accept(spec))
.withMessageContainingAll("Response header '" + LAST_MODIFIED + "'", expected, this.now);
}