Remove need for attached test-jar artifacts
Remove test-jar artifacts from Maven projects and relocate classes. The majority of utilities now live in the `spring-boot-testsupport` module. This update will help us to deploy artifacts using the standard Maven deploy plugin in the future (which doesn't support the filtering of individual artifacts). Fixes gh-9493
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.boot.testsupport.assertj;
|
||||
|
||||
import org.assertj.core.api.Condition;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.StringDescription;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Adapter class allowing a Hamcrest {@link Matcher} to be used as an AssertJ
|
||||
* {@link Condition}.
|
||||
*
|
||||
* @param <T> the type of object that the condition accepts
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public final class Matched<T> extends Condition<T> {
|
||||
|
||||
private final Matcher<? extends T> matcher;
|
||||
|
||||
private Matched(Matcher<? extends T> matcher) {
|
||||
Assert.notNull(matcher, "Matcher must not be null");
|
||||
this.matcher = matcher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(final T value) {
|
||||
if (this.matcher.matches(value)) {
|
||||
return true;
|
||||
}
|
||||
StringDescription description = new StringDescription();
|
||||
this.matcher.describeTo(description);
|
||||
describedAs(description.toString());
|
||||
return false;
|
||||
}
|
||||
|
||||
public static <T> Condition<T> when(Matcher<? extends T> matcher) {
|
||||
return by(matcher);
|
||||
}
|
||||
|
||||
public static <T> Condition<T> by(Matcher<? extends T> matcher) {
|
||||
return new Matched<>(matcher);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Utilities and helpers for AssertJ.
|
||||
*/
|
||||
package org.springframework.boot.testsupport.assertj;
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.junit.compiler;
|
||||
package org.springframework.boot.testsupport.compiler;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -17,4 +17,4 @@
|
||||
/**
|
||||
* Utilities to work with the Java compiler at test time.
|
||||
*/
|
||||
package org.springframework.boot.junit.compiler;
|
||||
package org.springframework.boot.testsupport.compiler;
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.boot.testsupport.context;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.asm.Opcodes;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.core.type.MethodMetadata;
|
||||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Abstract base class for {@code @Configuration} sanity checks.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public abstract class AbstractConfigurationClassTests {
|
||||
|
||||
private ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
|
||||
|
||||
@Test
|
||||
public void allBeanMethodsArePublic() throws IOException, ClassNotFoundException {
|
||||
Set<String> nonPublicBeanMethods = new HashSet<>();
|
||||
for (AnnotationMetadata configurationClass : findConfigurationClasses()) {
|
||||
Set<MethodMetadata> beanMethods = configurationClass
|
||||
.getAnnotatedMethods(Bean.class.getName());
|
||||
for (MethodMetadata methodMetadata : beanMethods) {
|
||||
if (!isPublic(methodMetadata)) {
|
||||
nonPublicBeanMethods.add(methodMetadata.getDeclaringClassName() + "."
|
||||
+ methodMetadata.getMethodName());
|
||||
}
|
||||
}
|
||||
}
|
||||
assertThat(nonPublicBeanMethods).as("Found non-public @Bean methods").isEmpty();
|
||||
}
|
||||
|
||||
private Set<AnnotationMetadata> findConfigurationClasses() throws IOException {
|
||||
Set<AnnotationMetadata> configurationClasses = new HashSet<>();
|
||||
Resource[] resources = this.resolver.getResources("classpath*:"
|
||||
+ getClass().getPackage().getName().replace('.', '/') + "/**/*.class");
|
||||
for (Resource resource : resources) {
|
||||
if (!isTestClass(resource)) {
|
||||
MetadataReader metadataReader = new SimpleMetadataReaderFactory()
|
||||
.getMetadataReader(resource);
|
||||
AnnotationMetadata annotationMetadata = metadataReader
|
||||
.getAnnotationMetadata();
|
||||
if (annotationMetadata.getAnnotationTypes()
|
||||
.contains(Configuration.class.getName())) {
|
||||
configurationClasses.add(annotationMetadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
return configurationClasses;
|
||||
}
|
||||
|
||||
private boolean isTestClass(Resource resource) throws IOException {
|
||||
return resource.getFile().getAbsolutePath()
|
||||
.contains("target" + File.separator + "test-classes");
|
||||
}
|
||||
|
||||
private boolean isPublic(MethodMetadata methodMetadata) {
|
||||
int access = (Integer) new DirectFieldAccessor(methodMetadata)
|
||||
.getPropertyValue("access");
|
||||
return (access & Opcodes.ACC_PUBLIC) != 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Utilities to help test Spring contexts.
|
||||
*/
|
||||
package org.springframework.boot.testsupport.context;
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Internal support classes used in Spring Boot tests.
|
||||
*/
|
||||
package org.springframework.boot.testsupport;
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.boot.testsupport.rule;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.junit.Assert;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
|
||||
import static org.hamcrest.Matchers.allOf;
|
||||
|
||||
/**
|
||||
* Internal JUnit {@code @Rule} to capture output from System.out and System.err.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class OutputCapture implements TestRule {
|
||||
|
||||
private CaptureOutputStream captureOut;
|
||||
|
||||
private CaptureOutputStream captureErr;
|
||||
|
||||
private ByteArrayOutputStream copy;
|
||||
|
||||
private List<Matcher<? super String>> matchers = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public Statement apply(final Statement base, Description description) {
|
||||
return new Statement() {
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
captureOutput();
|
||||
try {
|
||||
base.evaluate();
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
if (!OutputCapture.this.matchers.isEmpty()) {
|
||||
String output = OutputCapture.this.toString();
|
||||
Assert.assertThat(output, allOf(OutputCapture.this.matchers));
|
||||
}
|
||||
}
|
||||
finally {
|
||||
releaseOutput();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected void captureOutput() {
|
||||
// FIXME AnsiOutput.setEnabled(Enabled.NEVER);
|
||||
this.copy = new ByteArrayOutputStream();
|
||||
this.captureOut = new CaptureOutputStream(System.out, this.copy);
|
||||
this.captureErr = new CaptureOutputStream(System.err, this.copy);
|
||||
System.setOut(new PrintStream(this.captureOut));
|
||||
System.setErr(new PrintStream(this.captureErr));
|
||||
}
|
||||
|
||||
protected void releaseOutput() {
|
||||
// FIXME AnsiOutput.setEnabled(Enabled.DETECT);
|
||||
System.setOut(this.captureOut.getOriginal());
|
||||
System.setErr(this.captureErr.getOriginal());
|
||||
this.copy = null;
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
try {
|
||||
this.captureOut.flush();
|
||||
this.captureErr.flush();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
flush();
|
||||
return this.copy.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that the output is matched by the supplied {@code matcher}. Verification is
|
||||
* performed after the test method has executed.
|
||||
* @param matcher the matcher
|
||||
*/
|
||||
public void expect(Matcher<? super String> matcher) {
|
||||
this.matchers.add(matcher);
|
||||
}
|
||||
|
||||
private static class CaptureOutputStream extends OutputStream {
|
||||
|
||||
private final PrintStream original;
|
||||
|
||||
private final OutputStream copy;
|
||||
|
||||
CaptureOutputStream(PrintStream original, OutputStream copy) {
|
||||
this.original = original;
|
||||
this.copy = copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
this.copy.write(b);
|
||||
this.original.write(b);
|
||||
this.original.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b) throws IOException {
|
||||
write(b, 0, b.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
this.copy.write(b, off, len);
|
||||
this.original.write(b, off, len);
|
||||
}
|
||||
|
||||
public PrintStream getOriginal() {
|
||||
return this.original;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
this.copy.flush();
|
||||
this.original.flush();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.boot.testsupport.rule;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.Assume;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
|
||||
|
||||
/**
|
||||
* {@link TestRule} for working with an optional Redis server.
|
||||
*
|
||||
* @author Eric Bottard
|
||||
* @author Gary Russell
|
||||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class RedisTestServer implements TestRule {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(RedisTestServer.class);
|
||||
|
||||
private JedisConnectionFactory connectionFactory;
|
||||
|
||||
@Override
|
||||
public Statement apply(final Statement base, Description description) {
|
||||
try {
|
||||
this.connectionFactory = createConnectionFactory();
|
||||
return new RedisStatement(base, this.connectionFactory);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logger.error("No Redis server available", ex);
|
||||
return new SkipStatement();
|
||||
}
|
||||
}
|
||||
|
||||
private JedisConnectionFactory createConnectionFactory() {
|
||||
JedisConnectionFactory connectionFactory = new JedisConnectionFactory();
|
||||
connectionFactory.afterPropertiesSet();
|
||||
testConnection(connectionFactory);
|
||||
return connectionFactory;
|
||||
}
|
||||
|
||||
private void testConnection(JedisConnectionFactory connectionFactory) {
|
||||
connectionFactory.getConnection().close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Redis connection factory or {@code null} if the factory is not
|
||||
* available.
|
||||
* @return the connection factory or {@code null}
|
||||
*/
|
||||
public RedisConnectionFactory getConnectionFactory() {
|
||||
return this.connectionFactory;
|
||||
}
|
||||
|
||||
private static class RedisStatement extends Statement {
|
||||
|
||||
private final Statement base;
|
||||
|
||||
private final JedisConnectionFactory connectionFactory;
|
||||
|
||||
RedisStatement(Statement base, JedisConnectionFactory connectionFactory) {
|
||||
this.base = base;
|
||||
this.connectionFactory = connectionFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
try {
|
||||
this.base.evaluate();
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
this.connectionFactory.destroy();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logger.warn("Exception while trying to cleanup redis resource", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class SkipStatement extends Statement {
|
||||
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
Assume.assumeTrue("Skipping test due to " + "Redis ConnectionFactory"
|
||||
+ " not being available", false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Internal JUnit rules used in Spring Boot tests.
|
||||
*/
|
||||
package org.springframework.boot.testsupport.rule;
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.junit.runner.classpath;
|
||||
package org.springframework.boot.testsupport.runner.classpath;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.annotation.ElementType;
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.junit.runner.classpath;
|
||||
package org.springframework.boot.testsupport.runner.classpath;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.junit.runner.classpath;
|
||||
package org.springframework.boot.testsupport.runner.classpath;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.annotation.Annotation;
|
||||
@@ -17,4 +17,4 @@
|
||||
/**
|
||||
* Custom JUnit runner to change the classpath.
|
||||
*/
|
||||
package org.springframework.boot.junit.runner.classpath;
|
||||
package org.springframework.boot.testsupport.runner.classpath;
|
||||
@@ -17,4 +17,4 @@
|
||||
/**
|
||||
* Custom JUnit runners used in Spring Boot's own tests.
|
||||
*/
|
||||
package org.springframework.boot.junit.runner;
|
||||
package org.springframework.boot.testsupport.runner;
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.boot.testsupport.web.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
|
||||
/**
|
||||
* Simple example Filter used for testing.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class ExampleFilter implements Filter {
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response,
|
||||
FilterChain chain) throws IOException, ServletException {
|
||||
response.getWriter().write("[");
|
||||
chain.doFilter(request, response);
|
||||
response.getWriter().write("]");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.boot.testsupport.web.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.GenericServlet;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
/**
|
||||
* Simple example Servlet used for testing.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class ExampleServlet extends GenericServlet {
|
||||
|
||||
private final boolean echoRequestInfo;
|
||||
|
||||
private final boolean writeWithoutContentLength;
|
||||
|
||||
public ExampleServlet() {
|
||||
this(false, false);
|
||||
}
|
||||
|
||||
public ExampleServlet(boolean echoRequestInfo, boolean writeWithoutContentLength) {
|
||||
this.echoRequestInfo = echoRequestInfo;
|
||||
this.writeWithoutContentLength = writeWithoutContentLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void service(ServletRequest request, ServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
String content = "Hello World";
|
||||
if (this.echoRequestInfo) {
|
||||
content += " scheme=" + request.getScheme();
|
||||
content += " remoteaddr=" + request.getRemoteAddr();
|
||||
}
|
||||
if (this.writeWithoutContentLength) {
|
||||
response.setContentType("text/plain");
|
||||
ServletOutputStream outputStream = response.getOutputStream();
|
||||
StreamUtils.copy(content.getBytes(), outputStream);
|
||||
outputStream.flush();
|
||||
}
|
||||
else {
|
||||
response.getWriter().write(content);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.boot.testsupport.web.servlet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterRegistration;
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.Servlet;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRegistration;
|
||||
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Base class for Mock {@code ServletWebServer} implementations. Reduces the amount of
|
||||
* code that would otherwise be duplicated in {@code spring-boot},
|
||||
* {@code spring-boot-autoconfigure} and {@code spring-boot-actuator}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public abstract class MockServletWebServer {
|
||||
|
||||
private ServletContext servletContext;
|
||||
|
||||
private final Initializer[] initializers;
|
||||
|
||||
private final List<RegisteredServlet> registeredServlets = new ArrayList<>();
|
||||
|
||||
private final List<RegisteredFilter> registeredFilters = new ArrayList<>();
|
||||
|
||||
private final int port;
|
||||
|
||||
public MockServletWebServer(Initializer[] initializers, int port) {
|
||||
this.initializers = initializers;
|
||||
this.port = port;
|
||||
initialize();
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
try {
|
||||
this.servletContext = mock(ServletContext.class);
|
||||
given(this.servletContext.addServlet(anyString(), (Servlet) any()))
|
||||
.willAnswer(new Answer<ServletRegistration.Dynamic>() {
|
||||
@Override
|
||||
public ServletRegistration.Dynamic answer(
|
||||
InvocationOnMock invocation) throws Throwable {
|
||||
RegisteredServlet registeredServlet = new RegisteredServlet(
|
||||
(Servlet) invocation.getArguments()[1]);
|
||||
MockServletWebServer.this.registeredServlets
|
||||
.add(registeredServlet);
|
||||
return registeredServlet.getRegistration();
|
||||
}
|
||||
});
|
||||
given(this.servletContext.addFilter(anyString(), (Filter) any()))
|
||||
.willAnswer(new Answer<FilterRegistration.Dynamic>() {
|
||||
@Override
|
||||
public FilterRegistration.Dynamic answer(
|
||||
InvocationOnMock invocation) throws Throwable {
|
||||
RegisteredFilter registeredFilter = new RegisteredFilter(
|
||||
(Filter) invocation.getArguments()[1]);
|
||||
MockServletWebServer.this.registeredFilters
|
||||
.add(registeredFilter);
|
||||
return registeredFilter.getRegistration();
|
||||
}
|
||||
});
|
||||
final Map<String, String> initParameters = new HashMap<>();
|
||||
given(this.servletContext.setInitParameter(anyString(), anyString()))
|
||||
.will(new Answer<Void>() {
|
||||
@Override
|
||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
||||
initParameters.put(invocation.getArgument(0),
|
||||
invocation.getArgument(1));
|
||||
return null;
|
||||
}
|
||||
|
||||
});
|
||||
given(this.servletContext.getInitParameterNames())
|
||||
.willReturn(Collections.enumeration(initParameters.keySet()));
|
||||
given(this.servletContext.getInitParameter(anyString()))
|
||||
.willAnswer(new Answer<String>() {
|
||||
@Override
|
||||
public String answer(InvocationOnMock invocation)
|
||||
throws Throwable {
|
||||
return initParameters.get(invocation.getArgument(0));
|
||||
}
|
||||
});
|
||||
given(this.servletContext.getAttributeNames())
|
||||
.willReturn(MockServletWebServer.<String>emptyEnumeration());
|
||||
given(this.servletContext.getNamedDispatcher("default"))
|
||||
.willReturn(mock(RequestDispatcher.class));
|
||||
for (Initializer initializer : this.initializers) {
|
||||
initializer.onStartup(this.servletContext);
|
||||
}
|
||||
}
|
||||
catch (ServletException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
this.servletContext = null;
|
||||
this.registeredServlets.clear();
|
||||
}
|
||||
|
||||
public ServletContext getServletContext() {
|
||||
return this.servletContext;
|
||||
}
|
||||
|
||||
public Servlet[] getServlets() {
|
||||
Servlet[] servlets = new Servlet[this.registeredServlets.size()];
|
||||
for (int i = 0; i < servlets.length; i++) {
|
||||
servlets[i] = this.registeredServlets.get(i).getServlet();
|
||||
}
|
||||
return servlets;
|
||||
}
|
||||
|
||||
public RegisteredServlet getRegisteredServlet(int index) {
|
||||
return getRegisteredServlets().get(index);
|
||||
}
|
||||
|
||||
public List<RegisteredServlet> getRegisteredServlets() {
|
||||
return this.registeredServlets;
|
||||
}
|
||||
|
||||
public RegisteredFilter getRegisteredFilters(int index) {
|
||||
return getRegisteredFilters().get(index);
|
||||
}
|
||||
|
||||
public List<RegisteredFilter> getRegisteredFilters() {
|
||||
return this.registeredFilters;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return this.port;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Enumeration<T> emptyEnumeration() {
|
||||
return (Enumeration<T>) EmptyEnumeration.EMPTY_ENUMERATION;
|
||||
}
|
||||
|
||||
private static class EmptyEnumeration<E> implements Enumeration<E> {
|
||||
|
||||
static final MockServletWebServer.EmptyEnumeration<Object> EMPTY_ENUMERATION = new MockServletWebServer.EmptyEnumeration<>();
|
||||
|
||||
@Override
|
||||
public boolean hasMoreElements() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E nextElement() {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A registered servlet.
|
||||
*/
|
||||
public static class RegisteredServlet {
|
||||
|
||||
private final Servlet servlet;
|
||||
|
||||
private final ServletRegistration.Dynamic registration;
|
||||
|
||||
public RegisteredServlet(Servlet servlet) {
|
||||
this.servlet = servlet;
|
||||
this.registration = mock(ServletRegistration.Dynamic.class);
|
||||
}
|
||||
|
||||
public ServletRegistration.Dynamic getRegistration() {
|
||||
return this.registration;
|
||||
}
|
||||
|
||||
public Servlet getServlet() {
|
||||
return this.servlet;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A registered filter.
|
||||
*/
|
||||
public static class RegisteredFilter {
|
||||
|
||||
private final Filter filter;
|
||||
|
||||
private final FilterRegistration.Dynamic registration;
|
||||
|
||||
public RegisteredFilter(Filter filter) {
|
||||
this.filter = filter;
|
||||
this.registration = mock(FilterRegistration.Dynamic.class);
|
||||
}
|
||||
|
||||
public FilterRegistration.Dynamic getRegistration() {
|
||||
return this.registration;
|
||||
}
|
||||
|
||||
public Filter getFilter() {
|
||||
return this.filter;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializer (usually implement by adapting {@code Initializer}).
|
||||
*/
|
||||
protected interface Initializer {
|
||||
|
||||
void onStartup(ServletContext context) throws ServletException;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Servlet test support.
|
||||
*/
|
||||
package org.springframework.boot.testsupport.web.servlet;
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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
|
||||
*
|
||||
* http://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.boot.testsupport.assertj;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
|
||||
/**
|
||||
* Tests for {@link Matched}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class MatchedTests {
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void byMatcherMatches() {
|
||||
assertThat("1234").is(Matched.by(startsWith("12")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void byMatcherDoesNotMatch() {
|
||||
this.thrown.expect(AssertionError.class);
|
||||
this.thrown.expectMessage("a string starting with \"23\"");
|
||||
assertThat("1234").is(Matched.by(startsWith("23")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenMatcherMatches() {
|
||||
assertThat("1234").is(Matched.when(startsWith("12")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenMatcherDoesNotMatch() {
|
||||
this.thrown.expect(AssertionError.class);
|
||||
this.thrown.expectMessage("a string starting with \"23\"");
|
||||
assertThat("1234").is(Matched.when(startsWith("23")));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.junit.runner.classpath;
|
||||
package org.springframework.boot.testsupport.runner.classpath;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.junit.runner.classpath;
|
||||
package org.springframework.boot.testsupport.runner.classpath;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
Reference in New Issue
Block a user