Apply 'instanceof pattern matching' in spring-test and Servlet mocks

This commit is contained in:
Sam Brannen
2022-12-09 11:49:48 -05:00
parent aae46263cc
commit 485c80fcf3
25 changed files with 124 additions and 116 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2022 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.
@@ -69,8 +69,8 @@ public class MockBodyContent extends BodyContent {
}
private static JspWriter adaptJspWriter(@Nullable Writer targetWriter, @Nullable HttpServletResponse response) {
if (targetWriter instanceof JspWriter) {
return (JspWriter) targetWriter;
if (targetWriter instanceof JspWriter jspWriter) {
return jspWriter;
}
else {
return new MockJspWriter(response, targetWriter);

View File

@@ -167,11 +167,11 @@ public class MockHttpSession implements HttpSession {
if (value != null) {
Object oldValue = this.attributes.put(name, value);
if (value != oldValue) {
if (oldValue instanceof HttpSessionBindingListener) {
((HttpSessionBindingListener) oldValue).valueUnbound(new HttpSessionBindingEvent(this, name, oldValue));
if (oldValue instanceof HttpSessionBindingListener listener) {
listener.valueUnbound(new HttpSessionBindingEvent(this, name, oldValue));
}
if (value instanceof HttpSessionBindingListener) {
((HttpSessionBindingListener) value).valueBound(new HttpSessionBindingEvent(this, name, value));
if (value instanceof HttpSessionBindingListener listener) {
listener.valueBound(new HttpSessionBindingEvent(this, name, value));
}
}
}
@@ -185,8 +185,8 @@ public class MockHttpSession implements HttpSession {
assertIsValid();
Assert.notNull(name, "Attribute name must not be null");
Object value = this.attributes.remove(name);
if (value instanceof HttpSessionBindingListener) {
((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value));
if (value instanceof HttpSessionBindingListener listener) {
listener.valueUnbound(new HttpSessionBindingEvent(this, name, value));
}
}
@@ -199,8 +199,8 @@ public class MockHttpSession implements HttpSession {
String name = entry.getKey();
Object value = entry.getValue();
it.remove();
if (value instanceof HttpSessionBindingListener) {
((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value));
if (value instanceof HttpSessionBindingListener listener) {
listener.valueUnbound(new HttpSessionBindingEvent(this, name, value));
}
}
}
@@ -251,14 +251,14 @@ public class MockHttpSession implements HttpSession {
String name = entry.getKey();
Object value = entry.getValue();
it.remove();
if (value instanceof Serializable) {
state.put(name, (Serializable) value);
if (value instanceof Serializable serializable) {
state.put(name, serializable);
}
else {
// Not serializable... Servlet containers usually automatically
// unbind the attribute in this case.
if (value instanceof HttpSessionBindingListener) {
((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value));
if (value instanceof HttpSessionBindingListener listener) {
listener.valueUnbound(new HttpSessionBindingEvent(this, name, value));
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2022 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.
@@ -65,8 +65,8 @@ public class MockJspWriter extends JspWriter {
public MockJspWriter(@Nullable HttpServletResponse response, @Nullable Writer targetWriter) {
super(DEFAULT_BUFFER, true);
this.response = (response != null ? response : new MockHttpServletResponse());
if (targetWriter instanceof PrintWriter) {
this.targetWriter = (PrintWriter) targetWriter;
if (targetWriter instanceof PrintWriter printWriter) {
this.targetWriter = printWriter;
}
else if (targetWriter != null) {
this.targetWriter = new PrintWriter(targetWriter);

View File

@@ -342,13 +342,17 @@ public class MockPageContext extends PageContext {
}
public byte[] getContentAsByteArray() {
Assert.state(this.response instanceof MockHttpServletResponse, "MockHttpServletResponse required");
return ((MockHttpServletResponse) this.response).getContentAsByteArray();
if (this.response instanceof MockHttpServletResponse mockResponse) {
return mockResponse.getContentAsByteArray();
}
throw new IllegalStateException("MockHttpServletResponse is required");
}
public String getContentAsString() throws UnsupportedEncodingException {
Assert.state(this.response instanceof MockHttpServletResponse, "MockHttpServletResponse required");
return ((MockHttpServletResponse) this.response).getContentAsString();
if (this.response instanceof MockHttpServletResponse mockResponse) {
return mockResponse.getContentAsString();
}
throw new IllegalStateException("MockHttpServletResponse is required");
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2022 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.
@@ -78,11 +78,11 @@ public class MockRequestDispatcher implements RequestDispatcher {
* {@link HttpServletResponseWrapper} decorators if necessary.
*/
protected MockHttpServletResponse getMockHttpServletResponse(ServletResponse response) {
if (response instanceof MockHttpServletResponse) {
return (MockHttpServletResponse) response;
if (response instanceof MockHttpServletResponse mockResponse) {
return mockResponse;
}
if (response instanceof HttpServletResponseWrapper) {
return getMockHttpServletResponse(((HttpServletResponseWrapper) response).getResponse());
if (response instanceof HttpServletResponseWrapper wrapper) {
return getMockHttpServletResponse(wrapper.getResponse());
}
throw new IllegalArgumentException("MockRequestDispatcher requires MockHttpServletResponse");
}

View File

@@ -291,7 +291,7 @@ class MergedSqlConfig {
}
private static boolean isEmptyString(@Nullable Object value) {
return (value instanceof String && ((String) value).isEmpty());
return (value instanceof String str && str.isEmpty());
}
private static boolean isEmptyArray(@Nullable Object value) {

View File

@@ -138,8 +138,7 @@ abstract class AbstractExpressionEvaluatingCondition implements ExecutionConditi
// since the DirtiesContextTestExecutionListener will never be invoked for
// a disabled test class.
// See https://github.com/spring-projects/spring-framework/issues/26694
if (loadContext && result.isDisabled() && element instanceof Class) {
Class<?> testClass = (Class<?>) element;
if (loadContext && result.isDisabled() && element instanceof Class<?> testClass) {
DirtiesContext dirtiesContext = TestContextAnnotationUtils.findMergedAnnotation(testClass, DirtiesContext.class);
if (dirtiesContext != null) {
HierarchyMode hierarchyMode = dirtiesContext.hierarchyMode();
@@ -167,7 +166,7 @@ abstract class AbstractExpressionEvaluatingCondition implements ExecutionConditi
applicationContext = gac;
}
if (!(applicationContext instanceof ConfigurableApplicationContext)) {
if (!(applicationContext instanceof ConfigurableApplicationContext cac)) {
if (logger.isWarnEnabled()) {
String contextType = applicationContext.getClass().getName();
logger.warn(String.format("@%s(\"%s\") could not be evaluated on [%s] since the test " +
@@ -177,7 +176,7 @@ abstract class AbstractExpressionEvaluatingCondition implements ExecutionConditi
return false;
}
ConfigurableBeanFactory configurableBeanFactory = ((ConfigurableApplicationContext) applicationContext).getBeanFactory();
ConfigurableBeanFactory configurableBeanFactory = cac.getBeanFactory();
BeanExpressionResolver expressionResolver = configurableBeanFactory.getBeanExpressionResolver();
Assert.state(expressionResolver != null, "No BeanExpressionResolver");
BeanExpressionContext beanExpressionContext = new BeanExpressionContext(configurableBeanFactory, null);
@@ -189,11 +188,11 @@ abstract class AbstractExpressionEvaluatingCondition implements ExecutionConditi
gac.close();
}
if (result instanceof Boolean) {
return (Boolean) result;
if (result instanceof Boolean b) {
return b;
}
else if (result instanceof String) {
String str = ((String) result).trim().toLowerCase();
else if (result instanceof String str) {
str = str.trim().toLowerCase();
if ("true".equals(str)) {
return true;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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.
@@ -86,8 +86,8 @@ public abstract class TestConstructorUtils {
public static boolean isAutowirableConstructor(Executable executable, Class<?> testClass,
@Nullable PropertyProvider fallbackPropertyProvider) {
return (executable instanceof Constructor &&
isAutowirableConstructor((Constructor<?>) executable, testClass, fallbackPropertyProvider));
return (executable instanceof Constructor<?> constructor &&
isAutowirableConstructor(constructor, testClass, fallbackPropertyProvider));
}
/**

View File

@@ -32,7 +32,6 @@ import org.springframework.test.context.TestContext;
import org.springframework.test.context.TestExecutionListener;
import org.springframework.test.context.support.AbstractTestExecutionListener;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.util.Assert;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
@@ -193,9 +192,11 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener
if (context instanceof WebApplicationContext wac) {
ServletContext servletContext = wac.getServletContext();
Assert.state(servletContext instanceof MockServletContext, () -> String.format(
"The WebApplicationContext for test context %s must be configured with a MockServletContext.",
testContext));
if (!(servletContext instanceof MockServletContext mockServletContext)) {
throw new IllegalStateException(
"The WebApplicationContext for test context %s must be configured with a MockServletContext."
.formatted(testContext));
}
if (logger.isTraceEnabled()) {
logger.trace("Setting up MockHttpServletRequest, MockHttpServletResponse, ServletWebRequest, " +
@@ -206,7 +207,6 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener
"and RequestContextHolder for test class " + testContext.getTestClass().getName());
}
MockServletContext mockServletContext = (MockServletContext) servletContext;
MockHttpServletRequest request = new MockHttpServletRequest(mockServletContext);
request.setAttribute(CREATED_BY_THE_TESTCONTEXT_FRAMEWORK, Boolean.TRUE);
MockHttpServletResponse response = new MockHttpServletResponse();

View File

@@ -235,8 +235,8 @@ public class ContentRequestMatchers {
for (int i = 0; i < values.size(); i++) {
Object expected = values.get(i);
Object actual = actualMap.get(name).get(i);
if (expected instanceof Resource) {
expected = StreamUtils.copyToByteArray(((Resource) expected).getInputStream());
if (expected instanceof Resource resource) {
expected = StreamUtils.copyToByteArray(resource.getInputStream());
}
if (expected instanceof byte[]) {
assertTrue("Multipart is not a file", actual instanceof byte[]);

View File

@@ -280,8 +280,8 @@ class WiretapConnector implements ClientHttpConnector {
@Nullable
public Object getMockServerResult() {
return (getDelegate() instanceof MockServerClientHttpResponse ?
((MockServerClientHttpResponse) getDelegate()).getServerResult() : null);
return (getDelegate() instanceof MockServerClientHttpResponse mockResponse ?
mockResponse.getServerResult() : null);
}
}

View File

@@ -165,8 +165,8 @@ public final class MockMvc {
* @see org.springframework.test.web.servlet.result.MockMvcResultMatchers
*/
public ResultActions perform(RequestBuilder requestBuilder) throws Exception {
if (this.defaultRequestBuilder != null && requestBuilder instanceof Mergeable) {
requestBuilder = (RequestBuilder) ((Mergeable) requestBuilder).merge(this.defaultRequestBuilder);
if (this.defaultRequestBuilder != null && requestBuilder instanceof Mergeable mergeable) {
requestBuilder = (RequestBuilder) mergeable.merge(this.defaultRequestBuilder);
}
MockHttpServletRequest request = requestBuilder.buildRequest(this.servletContext);
@@ -187,8 +187,8 @@ public final class MockMvc {
mockResponse.setDefaultCharacterEncoding(this.defaultResponseCharacterEncoding.name());
}
if (requestBuilder instanceof SmartRequestBuilder) {
request = ((SmartRequestBuilder) requestBuilder).postProcessRequest(request);
if (requestBuilder instanceof SmartRequestBuilder smartRequestBuilder) {
request = smartRequestBuilder.postProcessRequest(request);
}
MvcResult mvcResult = new DefaultMvcResult(request, mockResponse);
@@ -227,8 +227,8 @@ public final class MockMvc {
}
private MockHttpServletResponse unwrapResponseIfNecessary(ServletResponse servletResponse) {
while (servletResponse instanceof HttpServletResponseWrapper) {
servletResponse = ((HttpServletResponseWrapper) servletResponse).getResponse();
while (servletResponse instanceof HttpServletResponseWrapper wrapper) {
servletResponse = wrapper.getResponse();
}
Assert.isInstanceOf(MockHttpServletResponse.class, servletResponse);
return (MockHttpServletResponse) servletResponse;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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.
@@ -73,8 +73,8 @@ final class TestDispatcherServlet extends DispatcherServlet {
if (request.getAsyncContext() != null) {
MockAsyncContext asyncContext;
if (request.getAsyncContext() instanceof MockAsyncContext) {
asyncContext = (MockAsyncContext) request.getAsyncContext();
if (request.getAsyncContext() instanceof MockAsyncContext mockAsyncContext) {
asyncContext = mockAsyncContext;
}
else {
MockHttpServletRequest mockRequest = WebUtils.getNativeRequest(request, MockHttpServletRequest.class);

View File

@@ -167,8 +167,8 @@ public class MockMvcHttpConnector implements ClientHttpConnector {
DataBufferUtils.release(buffer);
// Adapt to jakarta.servlet.http.Part...
MockPart mockPart = (part instanceof FilePart ?
new MockPart(part.name(), ((FilePart) part).filename(), partBytes) :
MockPart mockPart = (part instanceof FilePart filePart ?
new MockPart(part.name(), filePart.filename(), partBytes) :
new MockPart(part.name(), partBytes));
mockPart.getHeaders().putAll(part.headers());
requestBuilder.part(mockPart);

View File

@@ -36,7 +36,6 @@ import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.setup.ConfigurableMockMvcBuilder;
import org.springframework.test.web.servlet.setup.MockMvcConfigurer;
import org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder;
import org.springframework.util.Assert;
import org.springframework.validation.Validator;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.context.WebApplicationContext;
@@ -140,22 +139,25 @@ public interface MockMvcWebTestClient {
*/
static ResultActions resultActionsFor(ExchangeResult exchangeResult) {
Object serverResult = exchangeResult.getMockServerResult();
Assert.notNull(serverResult, "No MvcResult");
Assert.isInstanceOf(MvcResult.class, serverResult);
if (!(serverResult instanceof MvcResult mvcResult)) {
throw new IllegalArgumentException(
"Result from mock server exchange must be an instance of MvcResult instead of " +
(serverResult != null ? serverResult.getClass().getName() : "null"));
}
return new ResultActions() {
@Override
public ResultActions andExpect(ResultMatcher matcher) throws Exception {
matcher.match((MvcResult) serverResult);
matcher.match(mvcResult);
return this;
}
@Override
public ResultActions andDo(ResultHandler handler) throws Exception {
handler.handle((MvcResult) serverResult);
handler.handle(mvcResult);
return this;
}
@Override
public MvcResult andReturn() {
return (MvcResult) serverResult;
return mvcResult;
}
};
}

View File

@@ -423,17 +423,17 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
@Override
public Object merge(@Nullable Object parent) {
if (parent instanceof RequestBuilder) {
if (parent instanceof RequestBuilder requestBuilder) {
if (parent instanceof MockHttpServletRequestBuilder) {
MockHttpServletRequestBuilder copiedParent = MockMvcRequestBuilders.get("/");
copiedParent.merge(parent);
this.parentBuilder = copiedParent;
}
else {
this.parentBuilder = (RequestBuilder) parent;
this.parentBuilder = requestBuilder;
}
if (parent instanceof SmartRequestBuilder) {
this.parentPostProcessor = (SmartRequestBuilder) parent;
if (parent instanceof SmartRequestBuilder smartRequestBuilder) {
this.parentPostProcessor = smartRequestBuilder;
}
}
return this;

View File

@@ -98,7 +98,7 @@ public class MockMultipartHttpServletRequestBuilder extends MockHttpServletReque
/**
* Create a new MockMultipartFile with the given content.
* Add a new {@link MockMultipartFile} with the given content.
* @param name the name of the file
* @param content the content of the file
*/
@@ -108,7 +108,7 @@ public class MockMultipartHttpServletRequestBuilder extends MockHttpServletReque
}
/**
* Add the given MockMultipartFile.
* Add the given {@link MockMultipartFile}.
* @param file the multipart file
*/
public MockMultipartHttpServletRequestBuilder file(MockMultipartFile file) {
@@ -141,7 +141,6 @@ public class MockMultipartHttpServletRequestBuilder extends MockHttpServletReque
parentBuilder.parts.keySet().forEach(name ->
this.parts.putIfAbsent(name, parentBuilder.parts.get(name)));
}
}
else {
throw new IllegalArgumentException("Cannot merge with [" + parent.getClass().getName() + "]");
@@ -193,4 +192,5 @@ public class MockMultipartHttpServletRequestBuilder extends MockHttpServletReque
}
return defaultCharset;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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,6 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.springframework.test.util.AssertionErrors.assertEquals;
import static org.springframework.test.util.AssertionErrors.assertNotNull;
import static org.springframework.test.util.AssertionErrors.assertTrue;
import static org.springframework.test.util.AssertionErrors.fail;
/**
* Factory for assertions on the selected handler or handler method.
@@ -68,8 +67,8 @@ public class HandlerResultMatchers {
Object handler = result.getHandler();
assertNotNull("No handler", handler);
Class<?> actual = handler.getClass();
if (handler instanceof HandlerMethod) {
actual = ((HandlerMethod) handler).getBeanType();
if (handler instanceof HandlerMethod handlerMethod) {
actual = handlerMethod.getBeanType();
}
assertEquals("Handler type", type, ClassUtils.getUserClass(actual));
};
@@ -101,12 +100,12 @@ public class HandlerResultMatchers {
*/
public ResultMatcher methodCall(Object obj) {
return result -> {
if (!(obj instanceof MethodInvocationInfo)) {
fail(String.format("The supplied object [%s] is not an instance of %s. " +
"Ensure that you invoke the handler method via MvcUriComponentsBuilder.on().",
obj, MethodInvocationInfo.class.getName()));
if (!(obj instanceof MethodInvocationInfo invocationInfo)) {
throw new AssertionError("""
The supplied object [%s] is not an instance of %s. Ensure \
that you invoke the handler method via MvcUriComponentsBuilder.on()."""
.formatted(obj, MethodInvocationInfo.class.getName()));
}
MethodInvocationInfo invocationInfo = (MethodInvocationInfo) obj;
Method expected = invocationInfo.getControllerMethod();
Method actual = getHandlerMethod(result).getMethod();
assertEquals("Handler method", expected, actual);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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.
@@ -214,8 +214,8 @@ public class ModelResultMatchers {
return result -> {
ModelAndView mav = getModelAndView(result);
for (Object value : mav.getModel().values()) {
if (value instanceof Errors) {
assertFalse("Unexpected binding/validation errors: " + value, ((Errors) value).hasErrors());
if (value instanceof Errors errors) {
assertFalse("Unexpected binding/validation errors: " + value, errors.hasErrors());
}
}
};
@@ -252,8 +252,8 @@ public class ModelResultMatchers {
private int getErrorCount(ModelMap model) {
int count = 0;
for (Object value : model.values()) {
if (value instanceof Errors) {
count += ((Errors) value).getErrorCount();
if (value instanceof Errors errors) {
count += errors.getErrorCount();
}
}
return count;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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.
@@ -164,8 +164,8 @@ public abstract class AbstractMockMvcBuilder<B extends AbstractMockMvcBuilder<B>
if (this.defaultRequestBuilder == null) {
this.defaultRequestBuilder = MockMvcRequestBuilders.get("/");
}
if (this.defaultRequestBuilder instanceof ConfigurableSmartRequestBuilder) {
((ConfigurableSmartRequestBuilder) this.defaultRequestBuilder).with(processor);
if (this.defaultRequestBuilder instanceof ConfigurableSmartRequestBuilder configurableBuilder) {
configurableBuilder.with(processor);
}
}
}