diff --git a/spring-boot-test-autoconfigure/pom.xml b/spring-boot-test-autoconfigure/pom.xml
index 642446151e..55c810819f 100644
--- a/spring-boot-test-autoconfigure/pom.xml
+++ b/spring-boot-test-autoconfigure/pom.xml
@@ -29,6 +29,11 @@
spring-boot-autoconfigure
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ true
+ org.springframeworkspring-test
diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/AutoConfigureJsonTesters.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/AutoConfigureJsonTesters.java
new file mode 100644
index 0000000000..9da8de5209
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/AutoConfigureJsonTesters.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2012-2016 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.test.autoconfigure.json;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.boot.test.json.BasicJsonTester;
+import org.springframework.boot.test.json.GsonTester;
+import org.springframework.boot.test.json.JacksonTester;
+import org.springframework.context.ApplicationContext;
+import org.springframework.test.context.TestExecutionListeners;
+import org.springframework.test.context.TestExecutionListeners.MergeMode;
+
+/**
+ * Annotation that can be applied to a test class to enable and configure
+ * auto-configuration of JSON Testers.
+ *
+ * NOTE: {@code @AutoConfigureJsonTesters} works in conjunction with
+ * {@link JsonTesterInitializationTestExecutionListener}. If you declare your own
+ * {@link TestExecutionListeners @TestExecutionListeners} and don't
+ * {@link MergeMode#MERGE_WITH_DEFAULTS merge with defaults} you must include
+ * {@link JsonTesterInitializationTestExecutionListener} to use this annotation.
+ *
+ * @author Phillip Webb
+ * @see JsonTesterInitializationTestExecutionListener
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+public @interface AutoConfigureJsonTesters {
+
+ /**
+ * If {@link BasicJsonTester}, {@link JacksonTester} and {@link GsonTester} fields
+ * should be initialized using marshallers from the {@link ApplicationContext}.
+ */
+ boolean initFields() default true;
+
+}
diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/ImportJsonAutoConfiguration.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/ImportJsonAutoConfiguration.java
new file mode 100644
index 0000000000..7863d6c679
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/ImportJsonAutoConfiguration.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2012-2016 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.test.autoconfigure.json;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration;
+import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
+
+/**
+ * {@link ImportAutoConfiguration Auto-configuration imports} for typical JSON tests. Most
+ * tests should consider using {@link JsonTest @JsonTest} rather than using this
+ * annotation directly.
+ *
+ * @author Phillip Webb
+ * @since 1.4.0
+ * @see JsonTest
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@ImportAutoConfiguration({ GsonAutoConfiguration.class, JacksonAutoConfiguration.class })
+public @interface ImportJsonAutoConfiguration {
+
+}
diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/JsonExcludeFilter.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/JsonExcludeFilter.java
new file mode 100644
index 0000000000..0e5a73efe0
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/JsonExcludeFilter.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2012-2016 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.test.autoconfigure.json;
+
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import com.fasterxml.jackson.databind.Module;
+
+import org.springframework.boot.context.TypeExcludeFilter;
+import org.springframework.boot.jackson.JsonComponent;
+import org.springframework.boot.test.autoconfigure.filter.AnnotationCustomizableTypeExcludeFilter;
+import org.springframework.context.annotation.ComponentScan.Filter;
+import org.springframework.core.annotation.AnnotatedElementUtils;
+
+/**
+ * {@link TypeExcludeFilter} for {@link JsonTest @JsonTest}.
+ *
+ * @author Phillip Webb
+ */
+class JsonExcludeFilter extends AnnotationCustomizableTypeExcludeFilter {
+
+ private static final Set> DEFAULT_INCLUDES;
+
+ static {
+ Set> includes = new LinkedHashSet>();
+ includes.add(Module.class);
+ includes.add(JsonComponent.class);
+ DEFAULT_INCLUDES = Collections.unmodifiableSet(includes);
+ };
+
+ private final JsonTest annotation;
+
+ JsonExcludeFilter(Class> testClass) {
+ this.annotation = AnnotatedElementUtils.getMergedAnnotation(testClass,
+ JsonTest.class);
+ }
+
+ @Override
+ protected boolean hasAnnotation() {
+ return this.annotation != null;
+ }
+
+ @Override
+ protected Filter[] getFilters(FilterType type) {
+ switch (type) {
+ case INCLUDE:
+ return this.annotation.includeFilters();
+ case EXCLUDE:
+ return this.annotation.excludeFilters();
+ }
+ throw new IllegalStateException("Unsupported type " + type);
+ }
+
+ @Override
+ protected boolean isUseDefaultFilters() {
+ return this.annotation.useDefaultFilters();
+ }
+
+ @Override
+ protected Set> getDefaultIncudes() {
+ return DEFAULT_INCLUDES;
+ }
+
+}
diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/JsonTest.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/JsonTest.java
new file mode 100644
index 0000000000..6f0620e262
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/JsonTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2012-2016 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.test.autoconfigure.json;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.test.autoconfigure.OverrideAutoConfiguration;
+import org.springframework.boot.test.autoconfigure.filter.TypeExcludeFilters;
+import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
+import org.springframework.context.annotation.ComponentScan.Filter;
+import org.springframework.test.context.BootstrapWith;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@BootstrapWith(SpringBootTestContextBootstrapper.class)
+@OverrideAutoConfiguration(enabled = false)
+@TypeExcludeFilters(JsonExcludeFilter.class)
+@ImportJsonAutoConfiguration
+@AutoConfigureJsonTesters
+public @interface JsonTest {
+
+ /**
+ * Determines if default filtering should be used with
+ * {@link SpringBootApplication @SpringBootApplication}. By default only
+ * {@code @JsonComponent} and {@code Module} beans are included.
+ * @see #includeFilters()
+ * @see #excludeFilters()
+ */
+ boolean useDefaultFilters() default true;
+
+ /**
+ * A set of include filters which can be used to add otherwise filtered beans to the
+ * application context.
+ */
+ Filter[] includeFilters() default {};
+
+ /**
+ * A set of exclude filters which can be used to filter beans that would otherwise be
+ * added to the application context.
+ */
+ Filter[] excludeFilters() default {};
+}
diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/JsonTesterInitializationTestExecutionListener.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/JsonTesterInitializationTestExecutionListener.java
new file mode 100644
index 0000000000..26d9eb8338
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/JsonTesterInitializationTestExecutionListener.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2012-2016 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.test.autoconfigure.json;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.gson.Gson;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.ObjectFactory;
+import org.springframework.boot.test.json.BasicJsonTester;
+import org.springframework.boot.test.json.GsonTester;
+import org.springframework.boot.test.json.JacksonTester;
+import org.springframework.core.annotation.AnnotatedElementUtils;
+import org.springframework.test.context.TestContext;
+import org.springframework.test.context.TestExecutionListener;
+import org.springframework.test.context.support.AbstractTestExecutionListener;
+import org.springframework.util.ClassUtils;
+import org.springframework.util.ReflectionUtils;
+import org.springframework.util.ReflectionUtils.FieldCallback;
+
+/**
+ * {@link TestExecutionListener} to initialize JSON tester fields.
+ *
+ * @author Phillip Webb
+ * @since 1.4.0
+ */
+public class JsonTesterInitializationTestExecutionListener
+ extends AbstractTestExecutionListener {
+
+ private static final String ASSERTJ_CLASS = "org.assertj.core.api.Assert";
+
+ private static final Map> INITALIZERS;
+
+ static {
+ Map> initializers = new LinkedHashMap>();
+ initializers.put("com.fasterxml.jackson.databind.ObjectMapper",
+ JacksonInitializer.class);
+ initializers.put("com.google.gson.Gson", GsonInitializer.class);
+ INITALIZERS = Collections.unmodifiableMap(initializers);
+ }
+
+ @Override
+ public void prepareTestInstance(TestContext testContext) throws Exception {
+ ClassLoader classLoader = getClass().getClassLoader();
+ if (ClassUtils.isPresent(ASSERTJ_CLASS, classLoader)
+ && shouldInitializeFields(testContext)) {
+ initializeBasicJsonTesterFields(testContext);
+ initializeJsonMarshalTesterFields(classLoader, testContext);
+ }
+ }
+
+ private boolean shouldInitializeFields(TestContext testContext) {
+ AutoConfigureJsonTesters annotation = AnnotatedElementUtils.getMergedAnnotation(
+ testContext.getTestClass(), AutoConfigureJsonTesters.class);
+ return (annotation != null && annotation.initFields());
+ }
+
+ private void initializeBasicJsonTesterFields(final TestContext testContext) {
+ ReflectionUtils.doWithFields(testContext.getTestClass(), new FieldCallback() {
+
+ @Override
+ public void doWith(Field field)
+ throws IllegalArgumentException, IllegalAccessException {
+ if (BasicJsonTester.class.isAssignableFrom(field.getType())) {
+ setupField(field);
+ }
+ }
+
+ private void setupField(Field field) {
+ ReflectionUtils.makeAccessible(field);
+ Object existingInstance = ReflectionUtils.getField(field,
+ testContext.getTestInstance());
+ if (existingInstance == null) {
+ ReflectionUtils.setField(field, testContext.getTestInstance(),
+ new BasicJsonTester(testContext.getTestClass()));
+ }
+ }
+
+ });
+ }
+
+ private void initializeJsonMarshalTesterFields(ClassLoader classLoader,
+ TestContext testContext) {
+ for (Map.Entry> entry : INITALIZERS.entrySet()) {
+ if (ClassUtils.isPresent(entry.getKey(), classLoader)) {
+ initializeJsonMarshalTesterFields(classLoader, testContext,
+ entry.getKey(), entry.getValue());
+ }
+ }
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private void initializeJsonMarshalTesterFields(ClassLoader classLoader,
+ TestContext testContext, String marshallerClassName, Class> initializer) {
+ try {
+ Constructor> constructor = initializer.getDeclaredConstructor();
+ ReflectionUtils.makeAccessible(constructor);
+ initializeJsonMarshalTesterFields(testContext,
+ ClassUtils.resolveClassName(marshallerClassName, classLoader),
+ (Initializer) constructor.newInstance());
+ }
+ catch (Throwable ex) {
+ throw new IllegalStateException(ex);
+ }
+ }
+
+ private void initializeJsonMarshalTesterFields(final TestContext testContext,
+ final Class marshallerClass, Initializer initializer) {
+ initializer.initialize(testContext, new ObjectFactory() {
+
+ @Override
+ public T getObject() throws BeansException {
+ return testContext.getApplicationContext().getBean(marshallerClass);
+ }
+
+ });
+ }
+
+ /**
+ * Strategy used to initialize JSON testers without cause class not found exceptions.
+ * @param the marshaller type
+ */
+ interface Initializer {
+
+ void initialize(TestContext testContext, ObjectFactory marshaller);
+
+ }
+
+ /**
+ * {@link Initializer} for {@link JacksonTester}.
+ */
+ static class JacksonInitializer implements Initializer {
+
+ @Override
+ public void initialize(TestContext testContext,
+ ObjectFactory marshaller) {
+ JacksonTester.initFields(testContext.getTestInstance(), marshaller);
+ }
+
+ }
+
+ /**
+ * {@link Initializer} for {@link GsonTester}.
+ */
+ static class GsonInitializer implements Initializer {
+
+ @Override
+ public void initialize(TestContext testContext, ObjectFactory marshaller) {
+ GsonTester.initFields(testContext.getTestInstance(), marshaller);
+ }
+
+ }
+
+}
diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/package-info.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/package-info.java
new file mode 100644
index 0000000000..5e7b1bf37c
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/json/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2012-2016 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.
+ */
+
+/**
+ * Auto-configuration for JSON tests.
+ */
+package org.springframework.boot.test.autoconfigure.json;
diff --git a/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories
index 9689cc16ac..136c97df4e 100644
--- a/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories
+++ b/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories
@@ -6,4 +6,5 @@ org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCus
# Test Execution Listeners
org.springframework.test.context.TestExecutionListener=\
-org.springframework.boot.test.autoconfigure.AutoConfigureReportTestExecutionListener
+org.springframework.boot.test.autoconfigure.AutoConfigureReportTestExecutionListener,\
+org.springframework.boot.test.autoconfigure.json.JsonTesterInitializationTestExecutionListener
diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/ExampleBasicObject.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/ExampleBasicObject.java
new file mode 100644
index 0000000000..c2f337ca29
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/ExampleBasicObject.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2012-2016 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.test.autoconfigure.json;
+
+/**
+ * Example object to read/write as JSON.
+ *
+ * @author Phillip Webb
+ */
+public class ExampleBasicObject {
+
+ private String value;
+
+ public String getValue() {
+ return this.value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public int hashCode() {
+ return this.value.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj != null && obj.getClass().equals(getClass())) {
+ return this.value.equals(((ExampleBasicObject) obj).value);
+ }
+ return false;
+ }
+
+}
diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/ExampleCustomObject.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/ExampleCustomObject.java
new file mode 100644
index 0000000000..5cef2f416b
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/ExampleCustomObject.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2012-2016 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.test.autoconfigure.json;
+
+/**
+ * Example object to read/write as JSON via {@link ExampleJsonComponent}.
+ *
+ * @author Phillip Webb
+ */
+public class ExampleCustomObject {
+
+ private String value;
+
+ public ExampleCustomObject(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public int hashCode() {
+ return this.value.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj != null && obj.getClass().equals(getClass())) {
+ return this.value.equals(((ExampleCustomObject) obj).value);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return this.value;
+ }
+
+}
diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/ExampleJsonApplication.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/ExampleJsonApplication.java
new file mode 100644
index 0000000000..2161ea5811
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/ExampleJsonApplication.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2012-2016 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.test.autoconfigure.json;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * Example {@link SpringBootApplication @SpringBootApplication} for use with
+ * {@link JsonTest @JsonTest} tests.
+ *
+ * @author Phillip Webb
+ */
+@SpringBootApplication
+public class ExampleJsonApplication {
+
+}
diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/ExampleJsonComponent.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/ExampleJsonComponent.java
new file mode 100644
index 0000000000..8813e4b031
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/ExampleJsonComponent.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2012-2016 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.test.autoconfigure.json;
+
+import java.io.IOException;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.ObjectCodec;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.SerializerProvider;
+
+import org.springframework.boot.jackson.JsonComponent;
+import org.springframework.boot.jackson.JsonObjectDeserializer;
+import org.springframework.boot.jackson.JsonObjectSerializer;
+
+/**
+ * Example {@link JsonComponent} for use with {@link JsonTest @JsonTest} tests.
+ *
+ * @author Phillip Webb
+ */
+@JsonComponent
+public class ExampleJsonComponent {
+
+ public static class Serializer extends JsonObjectSerializer {
+
+ @Override
+ protected void serializeObject(ExampleCustomObject value, JsonGenerator jgen,
+ SerializerProvider provider) throws IOException {
+ jgen.writeStringField("value", value.toString());
+ }
+
+ }
+
+ public static class Deserialzer extends JsonObjectDeserializer {
+
+ @Override
+ protected ExampleCustomObject deserializeObject(JsonParser jasonParser,
+ DeserializationContext context, ObjectCodec codec, JsonNode tree)
+ throws IOException {
+ return new ExampleCustomObject(
+ nullSafeValue(tree.get("value"), String.class));
+ }
+
+ }
+
+}
diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/JsonTestIntegrationTests.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/JsonTestIntegrationTests.java
new file mode 100644
index 0000000000..0b165abace
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/JsonTestIntegrationTests.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2012-2016 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.test.autoconfigure.json;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.boot.test.json.BasicJsonTester;
+import org.springframework.boot.test.json.GsonTester;
+import org.springframework.boot.test.json.JacksonTester;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Integration tests for {@link JsonTest}.
+ *
+ * @author Phillip Webb
+ */
+@RunWith(SpringRunner.class)
+@JsonTest
+public class JsonTestIntegrationTests {
+
+ private BasicJsonTester basicJson;
+
+ private JacksonTester jacksonBasicJson;
+
+ private JacksonTester jacksonCustomJson;
+
+ private GsonTester gsonJson;
+
+ @Test
+ public void basicJson() throws Exception {
+ assertThat(this.basicJson.from("{\"a\":\"b\"}")).hasJsonPathStringValue("@.a");
+ }
+
+ @Test
+ public void jacksonBasic() throws Exception {
+ ExampleBasicObject object = new ExampleBasicObject();
+ object.setValue("spring");
+ assertThat(this.jacksonBasicJson.write(object)).isEqualToJson("example.json");
+ }
+
+ @Test
+ public void jacksonCustom() throws Exception {
+ ExampleCustomObject object = new ExampleCustomObject("spring");
+ assertThat(this.jacksonCustomJson.write(object)).isEqualToJson("example.json");
+ }
+
+ @Test
+ public void gson() throws Exception {
+ ExampleBasicObject object = new ExampleBasicObject();
+ object.setValue("spring");
+ assertThat(this.gsonJson.write(object)).isEqualToJson("example.json");
+ }
+
+}
diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/JsonTestWithAutoConfigureJsonTestersTests.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/JsonTestWithAutoConfigureJsonTestersTests.java
new file mode 100644
index 0000000000..4ecd1a99ff
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/JsonTestWithAutoConfigureJsonTestersTests.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2012-2016 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.test.autoconfigure.json;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.boot.test.json.BasicJsonTester;
+import org.springframework.boot.test.json.GsonTester;
+import org.springframework.boot.test.json.JacksonTester;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Integration tests for {@link JsonTest} with {@link AutoConfigureJsonTesters}.
+ *
+ * @author Phillip Webb
+ */
+@RunWith(SpringRunner.class)
+@JsonTest
+@AutoConfigureJsonTesters(initFields = false)
+public class JsonTestWithAutoConfigureJsonTestersTests {
+
+ private BasicJsonTester basicJson;
+
+ private JacksonTester jacksonTester;
+
+ private GsonTester gsonTester;
+
+ @Test
+ public void basicJson() throws Exception {
+ assertThat(this.basicJson).isNull();
+ }
+
+ @Test
+ public void jackson() throws Exception {
+ assertThat(this.jacksonTester).isNull();
+ }
+
+ @Test
+ public void gson() throws Exception {
+ assertThat(this.gsonTester).isNull();
+ }
+
+}
diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/JsonTesterInitializationTestExecutionListenerTests.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/JsonTesterInitializationTestExecutionListenerTests.java
new file mode 100644
index 0000000000..c568ffdcc7
--- /dev/null
+++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/json/JsonTesterInitializationTestExecutionListenerTests.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2012-2016 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.test.autoconfigure.json;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.gson.GsonBuilder;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import org.springframework.boot.test.json.BasicJsonTester;
+import org.springframework.boot.test.json.GsonTester;
+import org.springframework.boot.test.json.JacksonTester;
+import org.springframework.context.support.StaticApplicationContext;
+import org.springframework.test.context.TestContext;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.mock;
+
+/**
+ * Tests for {@link JsonTesterInitializationTestExecutionListener}.
+ *
+ * @author Phillip Webb
+ */
+public class JsonTesterInitializationTestExecutionListenerTests {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ private JsonTesterInitializationTestExecutionListener listener = new JsonTesterInitializationTestExecutionListener();
+
+ @Test
+ public void prepareTestContextShouldInitializeBasicJsonTester() throws Exception {
+ WithBasicJsonTester instance = new WithBasicJsonTester();
+ this.listener.prepareTestInstance(mockTestContext(instance));
+ assertThat(instance.tester).isNotNull();
+ }
+
+ @Test
+ public void prepareTestContextShouldInitializeJacksonTester() throws Exception {
+ WithJacksonTester instance = new WithJacksonTester();
+ this.listener.prepareTestInstance(mockTestContext(instance, new ObjectMapper()));
+ assertThat(instance.tester).isNotNull();
+ }
+
+ @Test
+ public void prepareTestContextShouldInitializeGsonTester() throws Exception {
+ WithGsonTester instance = new WithGsonTester();
+ this.listener.prepareTestInstance(
+ mockTestContext(instance, new GsonBuilder().create()));
+ assertThat(instance.tester).isNotNull();
+ }
+
+ @Test
+ public void prepareTestContextWhenInitFieldsFalseShouldNotInitializeTesters()
+ throws Exception {
+ WithInitFieldsFalse instance = new WithInitFieldsFalse();
+ this.listener.prepareTestInstance(mockTestContext(instance, new ObjectMapper()));
+ assertThat(instance.basicTester).isNull();
+ assertThat(instance.jacksonTester).isNull();
+ assertThat(instance.gsonTester).isNull();
+ }
+
+ @Test
+ public void prepareTestContextWhenInitFieldsTrueShouldInitializeTesters()
+ throws Exception {
+ WithInitFieldsTrue instance = new WithInitFieldsTrue();
+ this.listener.prepareTestInstance(mockTestContext(instance));
+ assertThat(instance.tester).isNotNull();
+ }
+
+ @Test
+ public void prepareTestContextWhenMissingAnnotationShouldNotInitializeTesters()
+ throws Exception {
+ WithoutAnnotation instance = new WithoutAnnotation();
+ this.listener.prepareTestInstance(mockTestContext(instance));
+ assertThat(instance.basicTester).isNull();
+ assertThat(instance.jacksonTester).isNull();
+ assertThat(instance.gsonTester).isNull();
+ }
+
+ @Test
+ public void prepareTestContextWhenHasJacksonTesterButNoObjectMapperBeanShouldThrowException()
+ throws Exception {
+ WithJacksonTester instance = new WithJacksonTester();
+ this.thrown.expect(IllegalStateException.class);
+ this.thrown.expectMessage("ObjectMapper");
+ this.listener.prepareTestInstance(mockTestContext(instance));
+ }
+
+ @Test
+ public void prepareTestContextWhenHasJacksonTesterButNoGsonBeanShouldThrowException()
+ throws Exception {
+ WithGsonTester instance = new WithGsonTester();
+ this.thrown.expect(IllegalStateException.class);
+ this.thrown.expectMessage("Gson");
+ this.listener.prepareTestInstance(mockTestContext(instance));
+ }
+
+ private TestContext mockTestContext(Object testInstance) {
+ return mockTestContext(testInstance, null);
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private TestContext mockTestContext(Object testInstance, Object bean) {
+ TestContext testContext = mock(TestContext.class);
+ StaticApplicationContext applicationContext = new StaticApplicationContext();
+ if (bean != null) {
+ applicationContext.getBeanFactory().registerSingleton("bean", bean);
+ }
+ given(testContext.getApplicationContext()).willReturn(applicationContext);
+ given(testContext.getTestClass()).willReturn((Class) testInstance.getClass());
+ given(testContext.getTestInstance()).willReturn(testInstance);
+ return testContext;
+ }
+
+ @AutoConfigureJsonTesters
+ static class WithBasicJsonTester {
+
+ private BasicJsonTester tester;
+
+ }
+
+ @AutoConfigureJsonTesters
+ static class WithJacksonTester {
+
+ private JacksonTester