Add @MockBean support
Add a `@MockBean` annotation which can be used to setup and inject mocks into an application context. The annotation can be used on test classes, test fields, configuration classes or configuration fields. When used on a field the annotation also acts as an injection point. Fixes gh-5042pull/5488/head
parent
0829a1bde8
commit
45c4f5f3f1
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Repeatable;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.MockSettings;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* Annotation that can be used to add mocks to a Spring {@link ApplicationContext}. Can be
|
||||
* used as a class level annotation or on fields in either {@code @Configuration} classes,
|
||||
* or test classes that are {@link RunWith @RunWith} the {@link SpringRunner}.
|
||||
* <p>
|
||||
* Mocks can be registered by type or by {@link #name() bean name}. Any existing single
|
||||
* bean of the same type defined in the context will be replaced by the mock, if no
|
||||
* existing bean is defined a new one will be added.
|
||||
* <p>
|
||||
* When {@code @MockBean} is used on a field, as well as being registered in the
|
||||
* application context, the mock will also be injected into the field. Typical usage might
|
||||
* be: <pre class="code">
|
||||
* @RunWith(SpringRunner.class)
|
||||
* public class ExampleTests {
|
||||
*
|
||||
* @MockBean
|
||||
* private ExampleService service;
|
||||
*
|
||||
* @Autowired
|
||||
* private UserOfService userOfService;
|
||||
*
|
||||
* @Test
|
||||
* public void testUserOfService() {
|
||||
* given(this.service.greet()).willReturn("Hello");
|
||||
* String actual = this.userOfService.makeUse();
|
||||
* assertEquals("Was: Hello", actual);
|
||||
* }
|
||||
*
|
||||
* @Configuration
|
||||
* @Import(UserOfService.class) // A @Component injected with ExampleService
|
||||
* static class Config {
|
||||
* }
|
||||
*
|
||||
*
|
||||
* }
|
||||
* </pre>
|
||||
* <p>
|
||||
* This annotation is {@code @Repeatable} and may be specified multiple times when working
|
||||
* with Java 8 or contained within an {@link MockBeans @MockBeans} annotation.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 1.4.0
|
||||
* @see MockitoPostProcessor
|
||||
*/
|
||||
@Target({ ElementType.TYPE, ElementType.FIELD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Repeatable(MockBeans.class)
|
||||
public @interface MockBean {
|
||||
|
||||
/**
|
||||
* The name of the bean that should be registered with the application context. If not
|
||||
* specified the name will either be generated or, if the mock replaces an existing
|
||||
* bean, the existing name will be used.
|
||||
*/
|
||||
String name() default "";
|
||||
|
||||
/**
|
||||
* The classes to mock. This is an alias of {@link #classes()} which can be used for
|
||||
* brevity if no other attributes are defined. See {@link #classes()} for details.
|
||||
*/
|
||||
@AliasFor("classes")
|
||||
Class<?>[] value() default {};
|
||||
|
||||
/**
|
||||
* The classes to mock. Each class specified here will result in a mock being created
|
||||
* and registered with the application context. Classes can be omitted when the
|
||||
* annotation is used on a field.
|
||||
* <p>
|
||||
* When {@code @MockBean} also defines a {@code name} this attribute can only contain
|
||||
* a single value.
|
||||
* <p>
|
||||
* If this is the only attribute specified consider using the {@code value} alais
|
||||
* instead.
|
||||
*/
|
||||
@AliasFor("value")
|
||||
Class<?>[] classes() default {};
|
||||
|
||||
/**
|
||||
* Any extra interfaces that should also be declared on the mock. See
|
||||
* {@link MockSettings#extraInterfaces(Class...)} for details.
|
||||
*/
|
||||
Class<?>[] extraInterfaces() default {};
|
||||
|
||||
/**
|
||||
* The {@link Answers} type to use on the mock.
|
||||
*/
|
||||
Answers answer() default Answers.RETURNS_DEFAULTS;
|
||||
|
||||
/**
|
||||
* If the generated mock is serializable. See {@link MockSettings#serializable()} for
|
||||
* details.
|
||||
*/
|
||||
boolean serializable() default false;
|
||||
|
||||
/**
|
||||
* The reset mode to apply to the mock bean. The default is {@link MockReset#AFTER}
|
||||
* meaning that mocks are automatically reset after each test method is invoked.
|
||||
*/
|
||||
MockReset reset() default MockReset.AFTER;
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Container annotation that aggregates several {@link MockBean} annotations.
|
||||
* <p>
|
||||
* Can be used natively, declaring several nested {@link MockBean} annotations. Can also
|
||||
* be used in conjunction with Java 8's support for <em>repeatable annotations</em>, where
|
||||
* {@link MockBean} can simply be declared several times on the same
|
||||
* {@linkplain ElementType#TYPE type}, implicitly generating this container annotation.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 1.4.0
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Documented
|
||||
public @interface MockBeans {
|
||||
|
||||
/**
|
||||
* Return the contained {@link MockBean} annotations.
|
||||
*/
|
||||
MockBean[] value();
|
||||
|
||||
}
|
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.MockSettings;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* A complete definition that can be used to create a Mockito mock.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class MockDefinition {
|
||||
|
||||
private static final int MULTIPLIER = 31;
|
||||
|
||||
private final String name;
|
||||
|
||||
private final Class<?> classToMock;
|
||||
|
||||
private final Set<Class<?>> extraInterfaces;
|
||||
|
||||
private final Answers answer;
|
||||
|
||||
private final boolean serializable;
|
||||
|
||||
private final MockReset reset;
|
||||
|
||||
MockDefinition(Class<?> classToMock) {
|
||||
this(null, classToMock, null, null, false, null);
|
||||
}
|
||||
|
||||
MockDefinition(String name, Class<?> classToMock, Class<?>[] extraInterfaces,
|
||||
Answers answer, boolean serializable, MockReset reset) {
|
||||
Assert.notNull(classToMock, "ClassToMock must not be null");
|
||||
this.name = name;
|
||||
this.classToMock = classToMock;
|
||||
this.extraInterfaces = asClassSet(extraInterfaces);
|
||||
this.answer = (answer != null ? answer : Answers.RETURNS_DEFAULTS);
|
||||
this.serializable = serializable;
|
||||
this.reset = (reset != null ? reset : MockReset.AFTER);
|
||||
}
|
||||
|
||||
private Set<Class<?>> asClassSet(Class<?>[] classes) {
|
||||
Set<Class<?>> classSet = new LinkedHashSet<Class<?>>();
|
||||
if (classes != null) {
|
||||
classSet.addAll(Arrays.asList(classes));
|
||||
}
|
||||
return Collections.unmodifiableSet(classSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name for bean.
|
||||
* @return the name or {@code null}
|
||||
*/
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the classes that should be mocked.
|
||||
* @return the class to mock; never {@code null}
|
||||
*/
|
||||
public Class<?> getClassToMock() {
|
||||
return this.classToMock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the extra interfaces.
|
||||
* @return the extra interfaces or an empty array
|
||||
*/
|
||||
public Set<Class<?>> getExtraInterfaces() {
|
||||
return this.extraInterfaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the answers mode.
|
||||
* @return the answer the answers mode; never {@code null}
|
||||
*/
|
||||
public Answers getAnswer() {
|
||||
return this.answer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if the mock is serializable.
|
||||
* @return if the mock is serializable
|
||||
*/
|
||||
public boolean isSerializable() {
|
||||
return this.serializable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mock reset mode.
|
||||
* @return the reset mode
|
||||
*/
|
||||
public MockReset getReset() {
|
||||
return this.reset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
result = MULTIPLIER * result + ObjectUtils.nullSafeHashCode(this.name);
|
||||
result = MULTIPLIER * result + ObjectUtils.nullSafeHashCode(this.classToMock);
|
||||
result = MULTIPLIER * result + ObjectUtils.nullSafeHashCode(this.extraInterfaces);
|
||||
result = MULTIPLIER * result + ObjectUtils.nullSafeHashCode(this.answer);
|
||||
result = MULTIPLIER * result + (this.serializable ? 1231 : 1237);
|
||||
result = MULTIPLIER * result + ObjectUtils.nullSafeHashCode(this.reset);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || obj.getClass() != getClass()) {
|
||||
return false;
|
||||
}
|
||||
MockDefinition other = (MockDefinition) obj;
|
||||
boolean result = true;
|
||||
result &= ObjectUtils.nullSafeEquals(this.name, other.name);
|
||||
result &= ObjectUtils.nullSafeEquals(this.classToMock, other.classToMock);
|
||||
result &= ObjectUtils.nullSafeEquals(this.extraInterfaces, other.extraInterfaces);
|
||||
result &= ObjectUtils.nullSafeEquals(this.answer, other.answer);
|
||||
result &= this.serializable == other.serializable;
|
||||
result &= ObjectUtils.nullSafeEquals(this.reset, other.reset);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this).append("name", this.name)
|
||||
.append("classToMock", this.classToMock)
|
||||
.append("extraInterfaces", this.extraInterfaces)
|
||||
.append("answer", this.answer).append("serializable", this.serializable)
|
||||
.append("reset", this.reset).build();
|
||||
}
|
||||
|
||||
public <T> T createMock() {
|
||||
return createMock(this.name);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T createMock(String name) {
|
||||
MockSettings settings = MockReset.withSettings(this.reset);
|
||||
if (StringUtils.hasLength(name)) {
|
||||
settings.name(name);
|
||||
}
|
||||
if (!this.extraInterfaces.isEmpty()) {
|
||||
settings.extraInterfaces(this.extraInterfaces.toArray(new Class<?>[] {}));
|
||||
}
|
||||
settings.defaultAnswer(this.answer.get());
|
||||
if (this.serializable) {
|
||||
settings.serializable();
|
||||
}
|
||||
return (T) Mockito.mock(this.classToMock, settings);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.ReflectionUtils.FieldCallback;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Parser to create {@link MockDefinition} from {@link MockBean @MockBean} annotations
|
||||
* declared on or in a class.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class MockDefinitionsParser {
|
||||
|
||||
private final Set<MockDefinition> definitions;
|
||||
|
||||
private final Map<MockDefinition, Field> fields;
|
||||
|
||||
MockDefinitionsParser() {
|
||||
this(Collections.<MockDefinition>emptySet());
|
||||
}
|
||||
|
||||
MockDefinitionsParser(Collection<? extends MockDefinition> existing) {
|
||||
this.definitions = new LinkedHashSet<MockDefinition>();
|
||||
this.fields = new LinkedHashMap<MockDefinition, Field>();
|
||||
if (existing != null) {
|
||||
this.definitions.addAll(existing);
|
||||
}
|
||||
}
|
||||
|
||||
public void parse(Class<?> source) {
|
||||
parseElement(source);
|
||||
ReflectionUtils.doWithFields(source, new FieldCallback() {
|
||||
|
||||
@Override
|
||||
public void doWith(Field field)
|
||||
throws IllegalArgumentException, IllegalAccessException {
|
||||
parseElement(field);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private void parseElement(AnnotatedElement element) {
|
||||
for (MockBean annotation : AnnotationUtils.getRepeatableAnnotations(element,
|
||||
MockBean.class, MockBeans.class)) {
|
||||
parseAnnotation(annotation, element);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseAnnotation(MockBean annotation, AnnotatedElement element) {
|
||||
Set<Class<?>> classesToMock = getOrDeduceClassesToMock(annotation, element);
|
||||
Assert.state(!classesToMock.isEmpty(),
|
||||
"Unable to deduce class to mock from " + element);
|
||||
if (StringUtils.hasLength(annotation.name())) {
|
||||
Assert.state(classesToMock.size() == 1,
|
||||
"The name attribute can only be used when mocking a single class");
|
||||
}
|
||||
for (Class<?> classToMock : classesToMock) {
|
||||
MockDefinition definition = new MockDefinition(annotation.name(), classToMock,
|
||||
annotation.extraInterfaces(), annotation.answer(),
|
||||
annotation.serializable(), annotation.reset());
|
||||
boolean isNewDefinition = this.definitions.add(definition);
|
||||
Assert.state(isNewDefinition, "Duplicate mock definition " + definition);
|
||||
if (element instanceof Field) {
|
||||
this.fields.put(definition, (Field) element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Set<Class<?>> getOrDeduceClassesToMock(MockBean annotation,
|
||||
AnnotatedElement element) {
|
||||
Set<Class<?>> classes = new LinkedHashSet<Class<?>>();
|
||||
classes.addAll(Arrays.asList(annotation.value()));
|
||||
if (classes.isEmpty() && element instanceof Field) {
|
||||
classes.add(((Field) element).getType());
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
|
||||
public Set<MockDefinition> getDefinitions() {
|
||||
return Collections.unmodifiableSet(this.definitions);
|
||||
}
|
||||
|
||||
public Field getField(MockDefinition definition) {
|
||||
return this.fields.get(definition);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.mockito.MockSettings;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.internal.util.MockUtil;
|
||||
import org.mockito.listeners.InvocationListener;
|
||||
import org.mockito.listeners.MethodInvocationReport;
|
||||
import org.mockito.mock.MockCreationSettings;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Reset strategy used on a mock bean. Usually applied to a mock via the
|
||||
* {@link MockBean @MockBean} annotation but can also be directly applied to any mock in
|
||||
* the {@code ApplicationContext} using the static methods.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @see ResetMocksTestExecutionListener
|
||||
*/
|
||||
public enum MockReset {
|
||||
|
||||
/**
|
||||
* Reset the mock before the test method runs.
|
||||
*/
|
||||
BEFORE,
|
||||
|
||||
/**
|
||||
* Reset the mock after the test method runs.
|
||||
*/
|
||||
AFTER,
|
||||
|
||||
/**
|
||||
* Don't reset the mock.
|
||||
*/
|
||||
NONE;
|
||||
|
||||
private static final MockUtil util = new MockUtil();
|
||||
|
||||
/**
|
||||
* Create {@link MockSettings settings} to be use used with mocks where reset should
|
||||
* occur before each test method runs.
|
||||
* @return mock settings
|
||||
*/
|
||||
public static MockSettings before() {
|
||||
return withSettings(BEFORE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create {@link MockSettings settings} to be use used with mocks where reset should
|
||||
* occur after each test method runs.
|
||||
* @return mock settings
|
||||
*/
|
||||
public static MockSettings after() {
|
||||
return withSettings(AFTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create {@link MockSettings settings} to be use used with mocks where a specific
|
||||
* reset should occur.
|
||||
* @param reset the reset type
|
||||
* @return mock settings
|
||||
*/
|
||||
public static MockSettings withSettings(MockReset reset) {
|
||||
return apply(reset, Mockito.withSettings());
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply {@link MockReset} to existing {@link MockSettings settings}.
|
||||
* @param reset the reset type
|
||||
* @param settings the settings
|
||||
* @return the configured settings
|
||||
*/
|
||||
public static MockSettings apply(MockReset reset, MockSettings settings) {
|
||||
Assert.notNull(settings, "Settings must not be null");
|
||||
if (reset != null && reset != NONE) {
|
||||
settings.invocationListeners(new ResetInvocationListener(reset));
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link MockReset} associated with the given mock.
|
||||
* @param mock the source mock
|
||||
* @return the reset type (never {@code null})
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
static MockReset get(Object mock) {
|
||||
MockReset reset = MockReset.NONE;
|
||||
if (util.isMock(mock)) {
|
||||
MockCreationSettings settings = util.getMockSettings(mock);
|
||||
List listeners = settings.getInvocationListeners();
|
||||
for (Object listener : listeners) {
|
||||
if (listener instanceof ResetInvocationListener) {
|
||||
reset = ((ResetInvocationListener) listener).getReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
return reset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy {@link InvocationListener} used to hold the {@link MockReset} value.
|
||||
*/
|
||||
private static class ResetInvocationListener implements InvocationListener {
|
||||
|
||||
private final MockReset reset;
|
||||
|
||||
ResetInvocationListener(MockReset reset) {
|
||||
this.reset = reset;
|
||||
}
|
||||
|
||||
public MockReset getReset() {
|
||||
return this.reset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportInvocation(MethodInvocationReport methodInvocationReport) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.test.context.ContextCustomizer;
|
||||
import org.springframework.test.context.MergedContextConfiguration;
|
||||
|
||||
/**
|
||||
* A {@link ContextCustomizer} to add Mockito support.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class MockitoContextCustomizer implements ContextCustomizer {
|
||||
|
||||
private final Set<MockDefinition> definitions;
|
||||
|
||||
MockitoContextCustomizer(Set<MockDefinition> definitions) {
|
||||
this.definitions = definitions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customizeContext(ConfigurableApplicationContext context,
|
||||
MergedContextConfiguration mergedContextConfiguration) {
|
||||
if (context instanceof BeanDefinitionRegistry) {
|
||||
MockitoPostProcessor.register((BeanDefinitionRegistry) context,
|
||||
this.definitions);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.definitions.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || obj.getClass() != getClass()) {
|
||||
return false;
|
||||
}
|
||||
MockitoContextCustomizer other = (MockitoContextCustomizer) obj;
|
||||
return this.definitions.equals(other.definitions);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.test.context.ContextConfigurationAttributes;
|
||||
import org.springframework.test.context.ContextCustomizer;
|
||||
import org.springframework.test.context.ContextCustomizerFactory;
|
||||
|
||||
/**
|
||||
* A {@link ContextCustomizerFactory} to add Mockito support.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class MockitoContextCustomizerFactory implements ContextCustomizerFactory {
|
||||
|
||||
@Override
|
||||
public ContextCustomizer createContextCustomizer(Class<?> testClass,
|
||||
List<ContextConfigurationAttributes> configAttributes) {
|
||||
// We gather the explicit mock definitions here since they form part of the
|
||||
// MergedContextConfiguration key. Different mocks need to have a different key
|
||||
MockDefinitionsParser parser = new MockDefinitionsParser();
|
||||
parser.parse(testClass);
|
||||
return new MockitoContextCustomizer(parser.getDefinitions());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.test.context.TestContext;
|
||||
import org.springframework.test.context.TestExecutionListener;
|
||||
import org.springframework.test.context.support.AbstractTestExecutionListener;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.ReflectionUtils.FieldCallback;
|
||||
|
||||
/**
|
||||
* {@link TestExecutionListener} to trigger {@link MockitoAnnotations#initMocks(Object)}
|
||||
* when {@link MockBean @MockBean} annotations are used. Primarily to allow {@link Captor}
|
||||
* annotations.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class MockitoInitializeTestExecutionListener extends AbstractTestExecutionListener {
|
||||
|
||||
@Override
|
||||
public void prepareTestInstance(TestContext testContext) throws Exception {
|
||||
if (hasMockitoAnnotations(testContext)) {
|
||||
MockitoAnnotations.initMocks(testContext.getTestInstance());
|
||||
}
|
||||
injectFields(testContext);
|
||||
}
|
||||
|
||||
private boolean hasMockitoAnnotations(TestContext testContext) {
|
||||
MockitoAnnotationCollection collector = new MockitoAnnotationCollection();
|
||||
ReflectionUtils.doWithFields(testContext.getTestClass(), collector);
|
||||
return collector.hasAnnotations();
|
||||
}
|
||||
|
||||
private void injectFields(TestContext testContext) {
|
||||
MockDefinitionsParser parser = new MockDefinitionsParser();
|
||||
parser.parse(testContext.getTestClass());
|
||||
if (!parser.getDefinitions().isEmpty()) {
|
||||
injectFields(testContext, parser);
|
||||
}
|
||||
}
|
||||
|
||||
private void injectFields(TestContext testContext, MockDefinitionsParser parser) {
|
||||
ApplicationContext applicationContext = testContext.getApplicationContext();
|
||||
MockitoPostProcessor postProcessor = applicationContext
|
||||
.getBean(MockitoPostProcessor.class);
|
||||
for (MockDefinition definition : parser.getDefinitions()) {
|
||||
Field field = parser.getField(definition);
|
||||
if (field != null) {
|
||||
postProcessor.inject(field, testContext.getTestInstance(), definition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link FieldCallback} to collect mockito annotations.
|
||||
*/
|
||||
private static class MockitoAnnotationCollection implements FieldCallback {
|
||||
|
||||
private final Set<Annotation> annotations = new LinkedHashSet<Annotation>();
|
||||
|
||||
@Override
|
||||
public void doWith(Field field)
|
||||
throws IllegalArgumentException, IllegalAccessException {
|
||||
for (Annotation annotation : field.getDeclaredAnnotations()) {
|
||||
if (annotation.annotationType().getName().startsWith("org.mockito")) {
|
||||
this.annotations.add(annotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasAnnotations() {
|
||||
return !this.annotations.isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,309 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.PropertyValues;
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
|
||||
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.BeanNameGenerator;
|
||||
import org.springframework.beans.factory.support.DefaultBeanNameGenerator;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
|
||||
import org.springframework.core.Conventions;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.ReflectionUtils.FieldCallback;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* A {@link BeanFactoryPostProcessor} used to register and inject
|
||||
* {@link MockBean @MockBeans} with the {@link ApplicationContext}. An initial set of
|
||||
* definitions can be passed to the processor with additional definitions being
|
||||
* automatically created from {@code @Configuration} classes that use
|
||||
* {@link MockBean @MockBean}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 1.4.0
|
||||
*/
|
||||
public class MockitoPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
|
||||
implements BeanClassLoaderAware, BeanFactoryAware, BeanFactoryPostProcessor,
|
||||
Ordered {
|
||||
|
||||
private static final String BEAN_NAME = MockitoPostProcessor.class.getName();
|
||||
|
||||
private static final String CONFIGURATION_CLASS_ATTRIBUTE = Conventions
|
||||
.getQualifiedAttributeName(ConfigurationClassPostProcessor.class,
|
||||
"configurationClass");
|
||||
|
||||
private final Set<MockDefinition> mockDefinitions;
|
||||
|
||||
private ClassLoader classLoader;
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
private final BeanNameGenerator beanNameGenerator = new DefaultBeanNameGenerator();
|
||||
|
||||
private Map<MockDefinition, String> beanNameRegistry = new HashMap<MockDefinition, String>();
|
||||
|
||||
private Map<Field, String> fieldRegistry = new HashMap<Field, String>();
|
||||
|
||||
/**
|
||||
* Create a new {@link MockitoPostProcessor} instance with the given initial
|
||||
* definitions.
|
||||
* @param mockDefinitions the initial definitions
|
||||
*/
|
||||
public MockitoPostProcessor(Set<MockDefinition> mockDefinitions) {
|
||||
this.mockDefinitions = mockDefinitions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
Assert.isInstanceOf(ConfigurableListableBeanFactory.class, beanFactory,
|
||||
"Mock beans can only be used with a ConfigurableListableBeanFactory");
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
|
||||
throws BeansException {
|
||||
Assert.isInstanceOf(BeanDefinitionRegistry.class, beanFactory,
|
||||
"@RegisterMocks can only be used on bean factories that "
|
||||
+ "implement BeanDefinitionRegistry");
|
||||
postProcessBeanFactory(beanFactory, (BeanDefinitionRegistry) beanFactory);
|
||||
}
|
||||
|
||||
private void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory,
|
||||
BeanDefinitionRegistry registry) {
|
||||
MockDefinitionsParser parser = new MockDefinitionsParser(this.mockDefinitions);
|
||||
for (Class<?> configurationClass : getConfigurationClasses(beanFactory)) {
|
||||
parser.parse(configurationClass);
|
||||
}
|
||||
Set<MockDefinition> definitions = parser.getDefinitions();
|
||||
for (MockDefinition definition : definitions) {
|
||||
Field field = parser.getField(definition);
|
||||
registerMock(beanFactory, registry, definition, field);
|
||||
}
|
||||
}
|
||||
|
||||
private Set<Class<?>> getConfigurationClasses(
|
||||
ConfigurableListableBeanFactory beanFactory) {
|
||||
Set<Class<?>> configurationClasses = new LinkedHashSet<Class<?>>();
|
||||
for (BeanDefinition beanDefinition : getConfigurationBeanDefinitions(beanFactory)
|
||||
.values()) {
|
||||
configurationClasses.add(ClassUtils.resolveClassName(
|
||||
beanDefinition.getBeanClassName(), this.classLoader));
|
||||
}
|
||||
return configurationClasses;
|
||||
}
|
||||
|
||||
private Map<String, BeanDefinition> getConfigurationBeanDefinitions(
|
||||
ConfigurableListableBeanFactory beanFactory) {
|
||||
Map<String, BeanDefinition> definitions = new LinkedHashMap<String, BeanDefinition>();
|
||||
for (String beanName : beanFactory.getBeanDefinitionNames()) {
|
||||
BeanDefinition definition = beanFactory.getBeanDefinition(beanName);
|
||||
if (definition.getAttribute(CONFIGURATION_CLASS_ATTRIBUTE) != null) {
|
||||
definitions.put(beanName, definition);
|
||||
}
|
||||
}
|
||||
return definitions;
|
||||
}
|
||||
|
||||
void inject(Field field, Object target, MockDefinition definition) {
|
||||
String beanName = this.beanNameRegistry.get(definition);
|
||||
Assert.state(StringUtils.hasLength(beanName),
|
||||
"No mock found for definition " + definition);
|
||||
injectMock(field, target, beanName);
|
||||
}
|
||||
|
||||
private void registerMock(ConfigurableListableBeanFactory beanFactory,
|
||||
BeanDefinitionRegistry registry, MockDefinition mockDefinition, Field field) {
|
||||
RootBeanDefinition beanDefinition = createBeanDefinition(mockDefinition);
|
||||
String name = getBeanName(beanFactory, registry, mockDefinition, beanDefinition);
|
||||
beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(1, name);
|
||||
registry.registerBeanDefinition(name, beanDefinition);
|
||||
this.beanNameRegistry.put(mockDefinition, name);
|
||||
if (field != null) {
|
||||
this.fieldRegistry.put(field, name);
|
||||
}
|
||||
}
|
||||
|
||||
private RootBeanDefinition createBeanDefinition(MockDefinition mockDefinition) {
|
||||
RootBeanDefinition definition = new RootBeanDefinition(
|
||||
mockDefinition.getClassToMock());
|
||||
definition.setTargetType(mockDefinition.getClassToMock());
|
||||
definition.setFactoryBeanName(BEAN_NAME);
|
||||
definition.setFactoryMethodName("createMock");
|
||||
definition.getConstructorArgumentValues().addIndexedArgumentValue(0,
|
||||
mockDefinition);
|
||||
return definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method used by defined beans to actually create the mock.
|
||||
* @param definition the mock definition
|
||||
* @param name the bean name
|
||||
* @return the mock instance
|
||||
*/
|
||||
protected final Object createMock(MockDefinition definition, String name) {
|
||||
return definition.createMock(name + " bean");
|
||||
}
|
||||
|
||||
private String getBeanName(ConfigurableListableBeanFactory beanFactory,
|
||||
BeanDefinitionRegistry registry, MockDefinition mockDefinition,
|
||||
RootBeanDefinition beanDefinition) {
|
||||
if (StringUtils.hasLength(mockDefinition.getName())) {
|
||||
return mockDefinition.getName();
|
||||
}
|
||||
String[] existingBeans = beanFactory
|
||||
.getBeanNamesForType(mockDefinition.getClassToMock());
|
||||
if (ObjectUtils.isEmpty(existingBeans)) {
|
||||
return this.beanNameGenerator.generateBeanName(beanDefinition, registry);
|
||||
}
|
||||
if (existingBeans.length == 1) {
|
||||
return existingBeans[0];
|
||||
}
|
||||
throw new IllegalStateException("Unable to register mock bean "
|
||||
+ mockDefinition.getClassToMock().getName()
|
||||
+ " expected a single existing bean to replace but found "
|
||||
+ new TreeSet<String>(Arrays.asList(existingBeans)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyValues postProcessPropertyValues(PropertyValues pvs,
|
||||
PropertyDescriptor[] pds, final Object bean, String beanName)
|
||||
throws BeansException {
|
||||
ReflectionUtils.doWithFields(bean.getClass(), new FieldCallback() {
|
||||
|
||||
@Override
|
||||
public void doWith(Field field)
|
||||
throws IllegalArgumentException, IllegalAccessException {
|
||||
postProcessField(bean, field);
|
||||
}
|
||||
|
||||
});
|
||||
return pvs;
|
||||
}
|
||||
|
||||
private void postProcessField(Object bean, Field field) {
|
||||
String beanName = this.fieldRegistry.get(field);
|
||||
if (StringUtils.hasLength(beanName)) {
|
||||
injectMock(field, bean, beanName);
|
||||
}
|
||||
}
|
||||
|
||||
private void injectMock(Field field, Object target, String beanName) {
|
||||
try {
|
||||
field.setAccessible(true);
|
||||
Object mockBean = this.beanFactory.getBean(beanName, field.getType());
|
||||
ReflectionUtils.setField(field, target, mockBean);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException("Could not inject mock field: " + field, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Ordered.LOWEST_PRECEDENCE - 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the processor with a {@link BeanDefinitionRegistry}. Not required when
|
||||
* using the {@link SpringRunner} as registration is automatic.
|
||||
* @param registry the bean definition registry
|
||||
*/
|
||||
public static void register(BeanDefinitionRegistry registry) {
|
||||
register(registry, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the processor with a {@link BeanDefinitionRegistry}. Not required when
|
||||
* using the {@link SpringRunner} as registration is automatic.
|
||||
* @param registry the bean definition registry
|
||||
* @param mockDefinitions the initial mock definitions
|
||||
*/
|
||||
public static void register(BeanDefinitionRegistry registry,
|
||||
Set<MockDefinition> mockDefinitions) {
|
||||
register(registry, MockitoPostProcessor.class, mockDefinitions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the processor with a {@link BeanDefinitionRegistry}. Not required when
|
||||
* using the {@link SpringRunner} as registration is automatic.
|
||||
* @param registry the bean definition registry
|
||||
* @param postProcessor the post processor class to register
|
||||
* @param mockDefinitions the initial mock definitions
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void register(BeanDefinitionRegistry registry,
|
||||
Class<? extends MockitoPostProcessor> postProcessor,
|
||||
Set<MockDefinition> mockDefinitions) {
|
||||
BeanDefinition definition = getOrAddBeanDefinition(registry, postProcessor);
|
||||
ValueHolder constructorArg = definition.getConstructorArgumentValues()
|
||||
.getIndexedArgumentValue(0, Set.class);
|
||||
Set<MockDefinition> existing = (Set<MockDefinition>) constructorArg.getValue();
|
||||
if (mockDefinitions != null) {
|
||||
existing.addAll(mockDefinitions);
|
||||
}
|
||||
}
|
||||
|
||||
private static BeanDefinition getOrAddBeanDefinition(BeanDefinitionRegistry registry,
|
||||
Class<? extends MockitoPostProcessor> postProcessor) {
|
||||
if (!registry.containsBeanDefinition(BEAN_NAME)) {
|
||||
RootBeanDefinition definition = new RootBeanDefinition(postProcessor);
|
||||
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
ConstructorArgumentValues constructorArguments = definition
|
||||
.getConstructorArgumentValues();
|
||||
constructorArguments.addIndexedArgumentValue(0,
|
||||
new LinkedHashSet<MockDefinition>());
|
||||
registry.registerBeanDefinition(BEAN_NAME, definition);
|
||||
return definition;
|
||||
}
|
||||
return registry.getBeanDefinition(BEAN_NAME);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.test.context.TestContext;
|
||||
import org.springframework.test.context.TestExecutionListener;
|
||||
import org.springframework.test.context.support.AbstractTestExecutionListener;
|
||||
|
||||
/**
|
||||
* {@link TestExecutionListener} to reset any mock beans that have been marked with a
|
||||
* {@link MockReset}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 1.4.0
|
||||
*/
|
||||
public class ResetMocksTestExecutionListener extends AbstractTestExecutionListener {
|
||||
|
||||
@Override
|
||||
public void beforeTestMethod(TestContext testContext) throws Exception {
|
||||
resetMocks(testContext.getApplicationContext(), MockReset.BEFORE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTestMethod(TestContext testContext) throws Exception {
|
||||
resetMocks(testContext.getApplicationContext(), MockReset.AFTER);
|
||||
}
|
||||
|
||||
private void resetMocks(ApplicationContext applicationContext, MockReset reset) {
|
||||
if (applicationContext instanceof ConfigurableApplicationContext) {
|
||||
resetMocks((ConfigurableApplicationContext) applicationContext, reset);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void resetMocks(ConfigurableApplicationContext applicationContext,
|
||||
MockReset reset) {
|
||||
ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
|
||||
String[] names = beanFactory.getBeanDefinitionNames();
|
||||
for (String name : names) {
|
||||
BeanDefinition definition = beanFactory.getBeanDefinition(name);
|
||||
if (AbstractBeanDefinition.SCOPE_DEFAULT.equals(definition.getScope())) {
|
||||
Object bean = beanFactory.getBean(name);
|
||||
if (reset.equals(MockReset.get(bean))) {
|
||||
Mockito.reset(bean);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (applicationContext.getParent() != null) {
|
||||
resetMocks(applicationContext.getParent(), reset);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Mockito integration for Spring Boot tests.
|
||||
*/
|
||||
package org.springframework.boot.test.mock.mockito;
|
@ -1,3 +1,9 @@
|
||||
# Spring Test ContextCustomizerFactories
|
||||
org.springframework.test.context.ContextCustomizerFactory=\
|
||||
org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizerFactory
|
||||
org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizerFactory,\
|
||||
org.springframework.boot.test.mock.mockito.MockitoContextCustomizerFactory
|
||||
|
||||
# Test Execution Listeners
|
||||
org.springframework.test.context.TestExecutionListener=\
|
||||
org.springframework.boot.test.mock.mockito.MockitoInitializeTestExecutionListener,\
|
||||
org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener
|
||||
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.internal.util.MockUtil;
|
||||
import org.mockito.mock.MockCreationSettings;
|
||||
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleExtraInterface;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleService;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link MockDefinition}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class MockDefinitionTests {
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void ClassToMockMustNotBeNull() throws Exception {
|
||||
this.thrown.expect(IllegalArgumentException.class);
|
||||
this.thrown.expectMessage("ClassToMock must not be null");
|
||||
new MockDefinition(null, null, null, null, false, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createWithDefaults() throws Exception {
|
||||
MockDefinition definition = new MockDefinition(null, ExampleService.class, null,
|
||||
null, false, null);
|
||||
assertThat(definition.getName()).isNull();
|
||||
assertThat(definition.getClassToMock()).isEqualTo(ExampleService.class);
|
||||
assertThat(definition.getExtraInterfaces()).isEmpty();
|
||||
assertThat(definition.getAnswer()).isEqualTo(Answers.RETURNS_DEFAULTS);
|
||||
assertThat(definition.isSerializable()).isFalse();
|
||||
assertThat(definition.getReset()).isEqualTo(MockReset.AFTER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createExplicit() throws Exception {
|
||||
MockDefinition definition = new MockDefinition("name", ExampleService.class,
|
||||
new Class<?>[] { ExampleExtraInterface.class },
|
||||
Answers.RETURNS_SMART_NULLS, true, MockReset.BEFORE);
|
||||
assertThat(definition.getName()).isEqualTo("name");
|
||||
assertThat(definition.getClassToMock()).isEqualTo(ExampleService.class);
|
||||
assertThat(definition.getExtraInterfaces())
|
||||
.containsExactly(ExampleExtraInterface.class);
|
||||
assertThat(definition.getAnswer()).isEqualTo(Answers.RETURNS_SMART_NULLS);
|
||||
assertThat(definition.isSerializable()).isTrue();
|
||||
assertThat(definition.getReset()).isEqualTo(MockReset.BEFORE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createMock() throws Exception {
|
||||
MockDefinition definition = new MockDefinition("name", ExampleService.class,
|
||||
new Class<?>[] { ExampleExtraInterface.class },
|
||||
Answers.RETURNS_SMART_NULLS, true, MockReset.BEFORE);
|
||||
ExampleService mock = definition.createMock();
|
||||
MockCreationSettings<?> settings = new MockUtil().getMockSettings(mock);
|
||||
assertThat(mock).isInstanceOf(ExampleService.class);
|
||||
assertThat(mock).isInstanceOf(ExampleExtraInterface.class);
|
||||
assertThat(settings.getMockName().toString()).isEqualTo("name");
|
||||
assertThat(settings.getDefaultAnswer())
|
||||
.isEqualTo(Answers.RETURNS_SMART_NULLS.get());
|
||||
assertThat(settings.isSerializable()).isTrue();
|
||||
assertThat(MockReset.get(mock)).isEqualTo(MockReset.BEFORE);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,184 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.mockito.Answers;
|
||||
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleExtraInterface;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleService;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
|
||||
import org.springframework.boot.test.mock.mockito.example.MyMockBean;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link MockDefinitionsParser}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class MockDefinitionsParserTests {
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private MockDefinitionsParser parser = new MockDefinitionsParser();
|
||||
|
||||
@Test
|
||||
public void parseSingleMockBean() {
|
||||
this.parser.parse(SingleMockBean.class);
|
||||
assertThat(getDefinitions()).hasSize(1);
|
||||
assertThat(getDefinition(0).getClassToMock()).isEqualTo(ExampleService.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseRepeatMockBean() {
|
||||
this.parser.parse(RepeatMockBean.class);
|
||||
assertThat(getDefinitions()).hasSize(2);
|
||||
assertThat(getDefinition(0).getClassToMock()).isEqualTo(ExampleService.class);
|
||||
assertThat(getDefinition(1).getClassToMock())
|
||||
.isEqualTo(ExampleServiceCaller.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore // See SPR-13973
|
||||
public void parseMetaMockBean() {
|
||||
this.parser.parse(MetaMockBean.class);
|
||||
assertThat(getDefinitions()).hasSize(1);
|
||||
assertThat(getDefinition(0).getClassToMock()).isEqualTo(ExampleService.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseMockBeanAttributes() throws Exception {
|
||||
this.parser.parse(MockBeanAttributes.class);
|
||||
assertThat(getDefinitions()).hasSize(1);
|
||||
MockDefinition definition = getDefinition(0);
|
||||
assertThat(definition.getName()).isEqualTo("Name");
|
||||
assertThat(definition.getClassToMock()).isEqualTo(ExampleService.class);
|
||||
assertThat(definition.getExtraInterfaces())
|
||||
.containsExactly(ExampleExtraInterface.class);
|
||||
assertThat(definition.getAnswer()).isEqualTo(Answers.RETURNS_SMART_NULLS);
|
||||
assertThat(definition.isSerializable()).isEqualTo(true);
|
||||
assertThat(definition.getReset()).isEqualTo(MockReset.NONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseOnClassAndField() throws Exception {
|
||||
this.parser.parse(OnClassAndField.class);
|
||||
assertThat(getDefinitions()).hasSize(2);
|
||||
assertThat(getDefinition(0).getClassToMock()).isEqualTo(ExampleService.class);
|
||||
assertThat(getDefinition(1).getClassToMock())
|
||||
.isEqualTo(ExampleServiceCaller.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseInferClassToMock() throws Exception {
|
||||
this.parser.parse(InferClassToMock.class);
|
||||
assertThat(getDefinitions()).hasSize(1);
|
||||
assertThat(getDefinition(0).getClassToMock()).isEqualTo(ExampleService.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseMissingClassToMock() throws Exception {
|
||||
this.thrown.expect(IllegalStateException.class);
|
||||
this.thrown.expectMessage("Unable to deduce class to mock");
|
||||
this.parser.parse(MissingClassToMock.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseMultipleClasses() throws Exception {
|
||||
this.parser.parse(MultipleClasses.class);
|
||||
assertThat(getDefinitions()).hasSize(2);
|
||||
assertThat(getDefinition(0).getClassToMock()).isEqualTo(ExampleService.class);
|
||||
assertThat(getDefinition(1).getClassToMock())
|
||||
.isEqualTo(ExampleServiceCaller.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseMultipleClassesWithName() throws Exception {
|
||||
this.thrown.expect(IllegalStateException.class);
|
||||
this.thrown.expectMessage(
|
||||
"The name attribute can only be used when mocking a single class");
|
||||
this.parser.parse(MultipleClassesWithName.class);
|
||||
}
|
||||
|
||||
private MockDefinition getDefinition(int index) {
|
||||
return getDefinitions().get(index);
|
||||
}
|
||||
|
||||
private List<MockDefinition> getDefinitions() {
|
||||
return new ArrayList<MockDefinition>(this.parser.getDefinitions());
|
||||
}
|
||||
|
||||
@MockBean(ExampleService.class)
|
||||
static class SingleMockBean {
|
||||
|
||||
}
|
||||
|
||||
@MockBeans({ @MockBean(ExampleService.class), @MockBean(ExampleServiceCaller.class) })
|
||||
static class RepeatMockBean {
|
||||
|
||||
}
|
||||
|
||||
@MyMockBean(ExampleService.class)
|
||||
static class MetaMockBean {
|
||||
|
||||
}
|
||||
|
||||
@MockBean(name = "Name", classes = ExampleService.class, extraInterfaces = ExampleExtraInterface.class, answer = Answers.RETURNS_SMART_NULLS, serializable = true, reset = MockReset.NONE)
|
||||
static class MockBeanAttributes {
|
||||
|
||||
}
|
||||
|
||||
@MockBean(ExampleService.class)
|
||||
static class OnClassAndField {
|
||||
|
||||
@MockBean(ExampleServiceCaller.class)
|
||||
private Object caller;
|
||||
|
||||
}
|
||||
|
||||
@MockBean({ ExampleService.class, ExampleServiceCaller.class })
|
||||
static class MultipleClasses {
|
||||
|
||||
}
|
||||
|
||||
@MockBean(name = "name", classes = { ExampleService.class,
|
||||
ExampleServiceCaller.class })
|
||||
static class MultipleClassesWithName {
|
||||
|
||||
}
|
||||
|
||||
static class InferClassToMock {
|
||||
|
||||
@MockBean
|
||||
private ExampleService exampleService;
|
||||
|
||||
}
|
||||
|
||||
@MockBean
|
||||
static class MissingClassToMock {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleService;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.withSettings;
|
||||
|
||||
/**
|
||||
* Tests for {@link MockReset}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class MockResetTests {
|
||||
|
||||
@Test
|
||||
public void noneAttachesReset() {
|
||||
ExampleService mock = mock(ExampleService.class);
|
||||
assertThat(MockReset.get(mock)).isEqualTo(MockReset.NONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withSettingsOfNoneAttachesReset() {
|
||||
ExampleService mock = mock(ExampleService.class,
|
||||
MockReset.withSettings(MockReset.NONE));
|
||||
assertThat(MockReset.get(mock)).isEqualTo(MockReset.NONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void beforeAttachesReset() {
|
||||
ExampleService mock = mock(ExampleService.class, MockReset.before());
|
||||
assertThat(MockReset.get(mock)).isEqualTo(MockReset.BEFORE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void afterAttachesReset() {
|
||||
ExampleService mock = mock(ExampleService.class, MockReset.after());
|
||||
assertThat(MockReset.get(mock)).isEqualTo(MockReset.AFTER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withSettingsAttachesReset() {
|
||||
ExampleService mock = mock(ExampleService.class,
|
||||
MockReset.withSettings(MockReset.BEFORE));
|
||||
assertThat(MockReset.get(mock)).isEqualTo(MockReset.BEFORE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void apply() throws Exception {
|
||||
ExampleService mock = mock(ExampleService.class,
|
||||
MockReset.apply(MockReset.AFTER, withSettings()));
|
||||
assertThat(MockReset.get(mock)).isEqualTo(MockReset.AFTER);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import org.springframework.test.context.ContextCustomizer;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link MockitoContextCustomizerFactory}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class MockitoContextCustomizerFactoryTests {
|
||||
|
||||
private final MockitoContextCustomizerFactory factory = new MockitoContextCustomizerFactory();
|
||||
|
||||
@Test
|
||||
public void getContextCustomizerWithoutAnnotationReturnsCustomizer()
|
||||
throws Exception {
|
||||
ContextCustomizer customizer = this.factory
|
||||
.createContextCustomizer(NoRegisterMocksAnnotation.class, null);
|
||||
assertThat(customizer).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getContextCustomizerWithAnnotationReturnsCustomizer() throws Exception {
|
||||
ContextCustomizer customizer = this.factory
|
||||
.createContextCustomizer(WithRegisterMocksAnnotation.class, null);
|
||||
assertThat(customizer).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getContextCustomizerUsesMocksAsCacheKey() throws Exception {
|
||||
ContextCustomizer customizer = this.factory
|
||||
.createContextCustomizer(WithRegisterMocksAnnotation.class, null);
|
||||
assertThat(customizer).isNotNull();
|
||||
ContextCustomizer same = this.factory
|
||||
.createContextCustomizer(WithSameRegisterMocksAnnotation.class, null);
|
||||
assertThat(customizer).isNotNull();
|
||||
ContextCustomizer different = this.factory.createContextCustomizer(
|
||||
WithDifferentRegisterMocksAnnotation.class, null);
|
||||
assertThat(customizer).isNotNull();
|
||||
assertThat(customizer.hashCode()).isEqualTo(same.hashCode());
|
||||
assertThat(customizer.hashCode()).isNotEqualTo(different.hashCode());
|
||||
assertThat(customizer).isEqualTo(customizer);
|
||||
assertThat(customizer).isEqualTo(same);
|
||||
assertThat(customizer).isNotEqualTo(different);
|
||||
}
|
||||
|
||||
static class NoRegisterMocksAnnotation {
|
||||
|
||||
}
|
||||
|
||||
@MockBean({ Service1.class, Service2.class })
|
||||
static class WithRegisterMocksAnnotation {
|
||||
|
||||
}
|
||||
|
||||
@MockBean({ Service2.class, Service1.class })
|
||||
static class WithSameRegisterMocksAnnotation {
|
||||
|
||||
}
|
||||
|
||||
@MockBean({ Service1.class })
|
||||
static class WithDifferentRegisterMocksAnnotation {
|
||||
|
||||
}
|
||||
|
||||
interface Service1 {
|
||||
|
||||
}
|
||||
|
||||
interface Service2 {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleService;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link MockitoContextCustomizer}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class MockitoContextCustomizerTests {
|
||||
|
||||
private static final Set<MockDefinition> NO_DEFINITIONS = Collections.emptySet();
|
||||
|
||||
@Test
|
||||
public void hashCodeAndEquals() {
|
||||
MockDefinition d1 = new MockDefinition(ExampleService.class);
|
||||
MockDefinition d2 = new MockDefinition(ExampleServiceCaller.class);
|
||||
MockitoContextCustomizer c1 = new MockitoContextCustomizer(NO_DEFINITIONS);
|
||||
MockitoContextCustomizer c2 = new MockitoContextCustomizer(
|
||||
new LinkedHashSet<MockDefinition>(Arrays.asList(d1, d2)));
|
||||
MockitoContextCustomizer c3 = new MockitoContextCustomizer(
|
||||
new LinkedHashSet<MockDefinition>(Arrays.asList(d2, d1)));
|
||||
assertThat(c2.hashCode()).isEqualTo(c3.hashCode());
|
||||
assertThat(c1).isEqualTo(c1).isNotEqualTo(c2);
|
||||
assertThat(c2).isEqualTo(c2).isEqualTo(c3).isNotEqualTo(c1);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.test.context.TestContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link MockitoInitializeTestExecutionListener}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class MockitoInitializeTestExecutionListenerTests {
|
||||
|
||||
private MockitoInitializeTestExecutionListener listener = new MockitoInitializeTestExecutionListener();
|
||||
|
||||
@Mock
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Mock
|
||||
private MockitoPostProcessor postProcessor;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<Field> fieldCaptor;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
given(this.applicationContext.getBean(MockitoPostProcessor.class))
|
||||
.willReturn(this.postProcessor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void prepareTestInstanceShouldInitMockitoAnnotation() throws Exception {
|
||||
WithMockitoAnnotation instance = new WithMockitoAnnotation();
|
||||
this.listener.prepareTestInstance(mockTestContext(instance));
|
||||
assertThat(instance.mock).isNotNull();
|
||||
assertThat(instance.captor).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void prepareTestInstanceShouldInjectMockBeans() throws Exception {
|
||||
WithMockBeans instance = new WithMockBeans();
|
||||
this.listener.prepareTestInstance(mockTestContext(instance));
|
||||
verify(this.postProcessor).inject(this.fieldCaptor.capture(), eq(instance),
|
||||
(MockDefinition) any());
|
||||
assertThat(this.fieldCaptor.getValue().getName()).isEqualTo("mockBean");
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
private TestContext mockTestContext(Object instance) {
|
||||
TestContext testContext = mock(TestContext.class);
|
||||
given(testContext.getTestInstance()).willReturn(instance);
|
||||
given(testContext.getTestClass()).willReturn((Class) instance.getClass());
|
||||
given(testContext.getApplicationContext()).willReturn(this.applicationContext);
|
||||
return testContext;
|
||||
}
|
||||
|
||||
static class WithMockitoAnnotation {
|
||||
|
||||
@Mock
|
||||
InputStream mock;
|
||||
|
||||
@Captor
|
||||
ArgumentCaptor<InputStream> captor;
|
||||
|
||||
}
|
||||
|
||||
static class WithMockBeans {
|
||||
|
||||
@MockBean
|
||||
InputStream mockBean;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleService;
|
||||
import org.springframework.boot.test.mock.mockito.example.FailingExampleService;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Test for {@link MockitoPostProcessor}. See also the integration tests in the
|
||||
* {@code runner} package.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class MockitoPostProcessorTests {
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void cannotMockMulipleBeans() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
MockitoPostProcessor.register(context);
|
||||
context.register(MultipleBeans.class);
|
||||
this.thrown.expect(IllegalStateException.class);
|
||||
this.thrown.expectMessage(
|
||||
"Unable to register mock bean " + ExampleService.class.getName()
|
||||
+ " expected a single existing bean to replace "
|
||||
+ "but found [example1, example2]");
|
||||
context.refresh();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@MockBean(ExampleService.class)
|
||||
static class MultipleBeans {
|
||||
|
||||
@Bean
|
||||
public ExampleService example1() {
|
||||
return new FailingExampleService();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ExampleService example2() {
|
||||
return new FailingExampleService();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleService;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
|
||||
import org.springframework.boot.test.mock.mockito.example.FailingExampleService;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
|
||||
/**
|
||||
* Test {@link MockBean} on a configuration class can be used to replace existing beans.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
public class OnConfigurationClassForExistingBeanIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private ExampleServiceCaller caller;
|
||||
|
||||
@Test
|
||||
public void testMocking() throws Exception {
|
||||
given(this.caller.getService().greeting()).willReturn("Boot");
|
||||
assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@MockBean(ExampleService.class)
|
||||
@Import({ ExampleServiceCaller.class, FailingExampleService.class })
|
||||
static class Config {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleService;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
|
||||
/**
|
||||
* Test {@link MockBean} on a configuration class can be used to inject new mock
|
||||
* instances.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
public class OnConfigurationClassForNewBeanIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private ExampleServiceCaller caller;
|
||||
|
||||
@Test
|
||||
public void testMocking() throws Exception {
|
||||
given(this.caller.getService().greeting()).willReturn("Boot");
|
||||
assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@MockBean(ExampleService.class)
|
||||
@Import(ExampleServiceCaller.class)
|
||||
static class Config {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleService;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
|
||||
import org.springframework.boot.test.mock.mockito.example.FailingExampleService;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
|
||||
/**
|
||||
* Test {@link MockBean} on a field on a {@code @Configuration} class can be used to
|
||||
* replace existing beans.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
public class OnConfigurationFieldForExistingBeanIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private Config config;
|
||||
|
||||
@Autowired
|
||||
private ExampleServiceCaller caller;
|
||||
|
||||
@Test
|
||||
public void testMocking() throws Exception {
|
||||
given(this.config.exampleService.greeting()).willReturn("Boot");
|
||||
assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import({ ExampleServiceCaller.class, FailingExampleService.class })
|
||||
static class Config {
|
||||
|
||||
@MockBean
|
||||
private ExampleService exampleService;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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.mock.mockito;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleService;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
|
||||
/**
|
||||
* Test {@link MockBean} on a field on a {@code @Configuration} class can be used to
|
||||
* inject new mock instances.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
public class OnConfigurationFieldForNewBeanIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private Config config;
|
||||
|
||||
@Autowired
|
||||
private ExampleServiceCaller caller;
|
||||
|
||||
@Test
|
||||
public void testMocking() throws Exception {
|
||||
given(this.config.exampleService.greeting()).willReturn("Boot");
|
||||
assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(ExampleServiceCaller.class)
|
||||
static class Config {
|
||||
|
||||
@MockBean
|
||||
private ExampleService exampleService;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.mock.mockito.OnContextHierarchyIntegrationTests.ChildConfig;
|
||||
import org.springframework.boot.test.mock.mockito.OnContextHierarchyIntegrationTests.ParentConfig;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleService;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.ContextHierarchy;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Test {@link MockBean} can be used with a {@link ContextHierarchy}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextHierarchy({ @ContextConfiguration(classes = ParentConfig.class),
|
||||
@ContextConfiguration(classes = ChildConfig.class) })
|
||||
public class OnContextHierarchyIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private ChildConfig childConfig;
|
||||
|
||||
@Test
|
||||
public void testMocking() throws Exception {
|
||||
ApplicationContext context = this.childConfig.getContext();
|
||||
ApplicationContext parentContext = context.getParent();
|
||||
assertThat(parentContext.getBeanNamesForType(ExampleService.class)).hasSize(1);
|
||||
assertThat(parentContext.getBeanNamesForType(ExampleServiceCaller.class))
|
||||
.hasSize(0);
|
||||
assertThat(context.getBeanNamesForType(ExampleService.class)).hasSize(0);
|
||||
assertThat(context.getBeanNamesForType(ExampleServiceCaller.class)).hasSize(1);
|
||||
assertThat(context.getBean(ExampleService.class)).isNotNull();
|
||||
assertThat(context.getBean(ExampleServiceCaller.class)).isNotNull();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@MockBean(ExampleService.class)
|
||||
static class ParentConfig {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@MockBean(ExampleServiceCaller.class)
|
||||
static class ChildConfig implements ApplicationContextAware {
|
||||
|
||||
private ApplicationContext context;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
this.context = applicationContext;
|
||||
}
|
||||
|
||||
public ApplicationContext getContext() {
|
||||
return this.context;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleService;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
|
||||
import org.springframework.boot.test.mock.mockito.example.FailingExampleService;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
|
||||
/**
|
||||
* Test {@link MockBean} on a test class can be used to replace existing beans.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@MockBean(ExampleService.class)
|
||||
public class OnTestClassForExistingBeanIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private ExampleServiceCaller caller;
|
||||
|
||||
@Test
|
||||
public void testMocking() throws Exception {
|
||||
given(this.caller.getService().greeting()).willReturn("Boot");
|
||||
assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import({ ExampleServiceCaller.class, FailingExampleService.class })
|
||||
static class Config {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleService;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
|
||||
/**
|
||||
* Test {@link MockBean} on a test class can be used to inject new mock instances.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@MockBean(ExampleService.class)
|
||||
public class OnTestClassForNewBeanIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private ExampleServiceCaller caller;
|
||||
|
||||
@Test
|
||||
public void testMocking() throws Exception {
|
||||
given(this.caller.getService().greeting()).willReturn("Boot");
|
||||
assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(ExampleServiceCaller.class)
|
||||
static class Config {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleService;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
|
||||
/**
|
||||
* Test {@link MockBean} on a test class field can be used to replace existing beans when
|
||||
* the context is cached. This test is identical to
|
||||
* {@link OnTestFieldForExistingBeanCacheIntegrationTests} so one of them should trigger
|
||||
* application context caching.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @see OnTestFieldForExistingBeanIntegrationTests
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration(classes = OnTestFieldForExistingBeanConfig.class)
|
||||
public class OnTestFieldForExistingBeanCacheIntegrationTests {
|
||||
|
||||
@MockBean
|
||||
private ExampleService exampleService;
|
||||
|
||||
@Autowired
|
||||
private ExampleServiceCaller caller;
|
||||
|
||||
@Test
|
||||
public void testMocking() throws Exception {
|
||||
given(this.exampleService.greeting()).willReturn("Boot");
|
||||
assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Config for {@link OnTestFieldForExistingBeanIntegrationTests} and
|
||||
* {@link OnTestFieldForExistingBeanCacheIntegrationTests}. Extracted to a shared config
|
||||
* to trigger caching.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Configuration
|
||||
@Import(ExampleServiceCaller.class)
|
||||
public class OnTestFieldForExistingBeanConfig {
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleService;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
|
||||
/**
|
||||
* Test {@link MockBean} on a test class field can be used to replace existing beans.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @see OnTestFieldForExistingBeanCacheIntegrationTests
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration(classes = OnTestFieldForExistingBeanConfig.class)
|
||||
public class OnTestFieldForExistingBeanIntegrationTests {
|
||||
|
||||
@MockBean
|
||||
private ExampleService exampleService;
|
||||
|
||||
@Autowired
|
||||
private ExampleServiceCaller caller;
|
||||
|
||||
@Test
|
||||
public void testMocking() throws Exception {
|
||||
given(this.exampleService.greeting()).willReturn("Boot");
|
||||
assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleService;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleServiceCaller;
|
||||
import org.springframework.boot.test.mock.mockito.example.FailingExampleService;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
|
||||
/**
|
||||
* Test {@link MockBean} on a test class field can be used to inject new mock instances.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
public class OnTestFieldForNewBeanIntegrationTests {
|
||||
|
||||
@MockBean
|
||||
private ExampleService exampleService;
|
||||
|
||||
@Autowired
|
||||
private ExampleServiceCaller caller;
|
||||
|
||||
@Test
|
||||
public void testMocking() throws Exception {
|
||||
given(this.exampleService.greeting()).willReturn("Boot");
|
||||
assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import({ ExampleServiceCaller.class, FailingExampleService.class })
|
||||
static class Config {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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.mock.mockito;
|
||||
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.MethodSorters;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.mock.mockito.example.ExampleService;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link ResetMocksTestExecutionListener}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class ResetMocksTestExecutionListenerTests {
|
||||
|
||||
static boolean test001executed;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void test001() {
|
||||
given(getMock("none").greeting()).willReturn("none");
|
||||
given(getMock("before").greeting()).willReturn("before");
|
||||
given(getMock("after").greeting()).willReturn("after");
|
||||
test001executed = true;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test002() {
|
||||
assertThat(getMock("none").greeting()).isEqualTo("none");
|
||||
assertThat(getMock("before").greeting()).isNull();
|
||||
assertThat(getMock("after").greeting()).isNull();
|
||||
}
|
||||
|
||||
public ExampleService getMock(String name) {
|
||||
return this.context.getBean(name, ExampleService.class);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
public ExampleService before() {
|
||||
return mock(ExampleService.class, MockReset.before());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ExampleService after() {
|
||||
return mock(ExampleService.class, MockReset.before());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ExampleService none() {
|
||||
return mock(ExampleService.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.mock.mockito.example;
|
||||
|
||||
/**
|
||||
* Example extra interface for mocking tests.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public interface ExampleExtraInterface {
|
||||
|
||||
String doExtra();
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.mock.mockito.example;
|
||||
|
||||
/**
|
||||
* Example service interface for mocking tests.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public interface ExampleService {
|
||||
|
||||
String greeting();
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.mock.mockito.example;
|
||||
|
||||
import java.security.Provider.Service;
|
||||
|
||||
/**
|
||||
* Example bean for mocking tests that calls {@link Service}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class ExampleServiceCaller {
|
||||
|
||||
private final ExampleService service;
|
||||
|
||||
public ExampleServiceCaller(ExampleService service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public ExampleService getService() {
|
||||
return this.service;
|
||||
}
|
||||
|
||||
public String sayGreeting() {
|
||||
return "I say " + this.service.greeting();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.mock.mockito.example;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* An {@link ExampleService} that always throws an exception.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Service
|
||||
public class FailingExampleService implements ExampleService {
|
||||
|
||||
@Override
|
||||
public String greeting() {
|
||||
throw new IllegalStateException("Failed");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.mock.mockito.example;
|
||||
|
||||
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.test.mock.mockito.MockBean;
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
|
||||
@Target({ ElementType.TYPE, ElementType.FIELD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@MockBean
|
||||
public @interface MyMockBean {
|
||||
|
||||
@AliasFor(annotation = MockBean.class, attribute = "value")
|
||||
Class<?> value();
|
||||
|
||||
}
|
Loading…
Reference in New Issue