/*
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.test.mock.mockito;
import java.util.ArrayList;
import java.util.List;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.Answers;
import org.springframework.beans.factory.annotation.Qualifier;
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.RealExampleService;
import org.springframework.util.ReflectionUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link DefinitionsParser}.
*
* @author Phillip Webb
*/
public class DefinitionsParserTests {
@Rule
public ExpectedException thrown = ExpectedException.none();
private DefinitionsParser parser = new DefinitionsParser();
@Test
public void parseSingleMockBean() {
this.parser.parse(SingleMockBean.class);
assertThat(getDefinitions()).hasSize(1);
assertThat(getMockDefinition(0).getTypeToMock().resolve())
.isEqualTo(ExampleService.class);
}
@Test
public void parseRepeatMockBean() {
this.parser.parse(RepeatMockBean.class);
assertThat(getDefinitions()).hasSize(2);
assertThat(getMockDefinition(0).getTypeToMock().resolve())
.isEqualTo(ExampleService.class);
assertThat(getMockDefinition(1).getTypeToMock().resolve())
.isEqualTo(ExampleServiceCaller.class);
}
@Test
public void parseMockBeanAttributes() throws Exception {
this.parser.parse(MockBeanAttributes.class);
assertThat(getDefinitions()).hasSize(1);
MockDefinition definition = getMockDefinition(0);
assertThat(definition.getName()).isEqualTo("Name");
assertThat(definition.getTypeToMock().resolve()).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);
assertThat(definition.getQualifier()).isNull();
}
@Test
public void parseMockBeanOnClassAndField() throws Exception {
this.parser.parse(MockBeanOnClassAndField.class);
assertThat(getDefinitions()).hasSize(2);
MockDefinition classDefinition = getMockDefinition(0);
assertThat(classDefinition.getTypeToMock().resolve())
.isEqualTo(ExampleService.class);
assertThat(classDefinition.getQualifier()).isNull();
MockDefinition fieldDefinition = getMockDefinition(1);
assertThat(fieldDefinition.getTypeToMock().resolve())
.isEqualTo(ExampleServiceCaller.class);
QualifierDefinition qualifier = QualifierDefinition.forElement(
ReflectionUtils.findField(MockBeanOnClassAndField.class, "caller"));
assertThat(fieldDefinition.getQualifier()).isNotNull().isEqualTo(qualifier);
}
@Test
public void parseMockBeanInferClassToMock() throws Exception {
this.parser.parse(MockBeanInferClassToMock.class);
assertThat(getDefinitions()).hasSize(1);
assertThat(getMockDefinition(0).getTypeToMock().resolve())
.isEqualTo(ExampleService.class);
}
@Test
public void parseMockBeanMissingClassToMock() throws Exception {
this.thrown.expect(IllegalStateException.class);
this.thrown.expectMessage("Unable to deduce type to mock");
this.parser.parse(MockBeanMissingClassToMock.class);
}
@Test
public void parseMockBeanMultipleClasses() throws Exception {
this.parser.parse(MockBeanMultipleClasses.class);
assertThat(getDefinitions()).hasSize(2);
assertThat(getMockDefinition(0).getTypeToMock().resolve())
.isEqualTo(ExampleService.class);
assertThat(getMockDefinition(1).getTypeToMock().resolve())
.isEqualTo(ExampleServiceCaller.class);
}
@Test
public void parseMockBeanMultipleClassesWithName() 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(MockBeanMultipleClassesWithName.class);
}
@Test
public void parseSingleSpyBean() {
this.parser.parse(SingleSpyBean.class);
assertThat(getDefinitions()).hasSize(1);
assertThat(getSpyDefinition(0).getTypeToSpy().resolve())
.isEqualTo(RealExampleService.class);
}
@Test
public void parseRepeatSpyBean() {
this.parser.parse(RepeatSpyBean.class);
assertThat(getDefinitions()).hasSize(2);
assertThat(getSpyDefinition(0).getTypeToSpy().resolve())
.isEqualTo(RealExampleService.class);
assertThat(getSpyDefinition(1).getTypeToSpy().resolve())
.isEqualTo(ExampleServiceCaller.class);
}
@Test
public void parseSpyBeanAttributes() throws Exception {
this.parser.parse(SpyBeanAttributes.class);
assertThat(getDefinitions()).hasSize(1);
SpyDefinition definition = getSpyDefinition(0);
assertThat(definition.getName()).isEqualTo("Name");
assertThat(definition.getTypeToSpy().resolve())
.isEqualTo(RealExampleService.class);
assertThat(definition.getReset()).isEqualTo(MockReset.NONE);
assertThat(definition.getQualifier()).isNull();
}
@Test
public void parseSpyBeanOnClassAndField() throws Exception {
this.parser.parse(SpyBeanOnClassAndField.class);
assertThat(getDefinitions()).hasSize(2);
SpyDefinition classDefinition = getSpyDefinition(0);
assertThat(classDefinition.getQualifier()).isNull();
assertThat(classDefinition.getTypeToSpy().resolve())
.isEqualTo(RealExampleService.class);
SpyDefinition fieldDefinition = getSpyDefinition(1);
QualifierDefinition qualifier = QualifierDefinition.forElement(
ReflectionUtils.findField(SpyBeanOnClassAndField.class, "caller"));
assertThat(fieldDefinition.getQualifier()).isNotNull().isEqualTo(qualifier);
assertThat(fieldDefinition.getTypeToSpy().resolve())
.isEqualTo(ExampleServiceCaller.class);
}
@Test
public void parseSpyBeanInferClassToMock() throws Exception {
this.parser.parse(SpyBeanInferClassToMock.class);
assertThat(getDefinitions()).hasSize(1);
assertThat(getSpyDefinition(0).getTypeToSpy().resolve())
.isEqualTo(RealExampleService.class);
}
@Test
public void parseSpyBeanMissingClassToMock() throws Exception {
this.thrown.expect(IllegalStateException.class);
this.thrown.expectMessage("Unable to deduce type to spy");
this.parser.parse(SpyBeanMissingClassToMock.class);
}
@Test
public void parseSpyBeanMultipleClasses() throws Exception {
this.parser.parse(SpyBeanMultipleClasses.class);
assertThat(getDefinitions()).hasSize(2);
assertThat(getSpyDefinition(0).getTypeToSpy().resolve())
.isEqualTo(RealExampleService.class);
assertThat(getSpyDefinition(1).getTypeToSpy().resolve())
.isEqualTo(ExampleServiceCaller.class);
}
@Test
public void parseSpyBeanMultipleClassesWithName() throws Exception {
this.thrown.expect(IllegalStateException.class);
this.thrown.expectMessage(
"The name attribute can only be used when spying a single class");
this.parser.parse(SpyBeanMultipleClassesWithName.class);
}
private MockDefinition getMockDefinition(int index) {
return (MockDefinition) getDefinitions().get(index);
}
private SpyDefinition getSpyDefinition(int index) {
return (SpyDefinition) getDefinitions().get(index);
}
private List<Definition> getDefinitions() {
return new ArrayList<>(this.parser.getDefinitions());
}
@MockBean(ExampleService.class)
static class SingleMockBean {
}
@MockBeans({ @MockBean(ExampleService.class), @MockBean(ExampleServiceCaller.class) })
static class RepeatMockBean {
}
@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 MockBeanOnClassAndField {
@MockBean(ExampleServiceCaller.class)
@Qualifier("test")
private Object caller;
}
@MockBean({ ExampleService.class, ExampleServiceCaller.class })
static class MockBeanMultipleClasses {
}
@MockBean(name = "name", classes = { ExampleService.class,
ExampleServiceCaller.class })
static class MockBeanMultipleClassesWithName {
}
static class MockBeanInferClassToMock {
@MockBean
private ExampleService exampleService;
}
@MockBean
static class MockBeanMissingClassToMock {
}
@SpyBean(RealExampleService.class)
static class SingleSpyBean {
}
@SpyBeans({ @SpyBean(RealExampleService.class),
@SpyBean(ExampleServiceCaller.class) })
static class RepeatSpyBean {
}
@SpyBean(name = "Name", classes = RealExampleService.class, reset = MockReset.NONE)
static class SpyBeanAttributes {
}
@SpyBean(RealExampleService.class)
static class SpyBeanOnClassAndField {
@SpyBean(ExampleServiceCaller.class)
@Qualifier("test")
private Object caller;
}
@SpyBean({ RealExampleService.class, ExampleServiceCaller.class })
static class SpyBeanMultipleClasses {
}
@SpyBean(name = "name", classes = { RealExampleService.class,
ExampleServiceCaller.class })
static class SpyBeanMultipleClassesWithName {
}
static class SpyBeanInferClassToMock {
@SpyBean
private RealExampleService exampleService;
}
@SpyBean
static class SpyBeanMissingClassToMock {
}
}