Make spring-boot-test compatible with Mockito 2.1 and 2.2

We use some internal Mockito classes and some  breaking API changes
have been made to them in Mockito 2. This commit introduces a utility
class, SpringBootMockUtil, to shield our code from these differences.
Mockito 1 is called directly and Mockito 2 is called via reflection.

To allow these changes to be tested, FilteredClassPathRunner has been
enhanced to also support overriding a dependency on the class path.
As a result it has been renamed to ModifiedClassPathRunner. The new
ClassPathOverrides annotation can be used to provide the Maven
coordinates of one or more dependencies that should be resolved and
added to the class path. Such additions are added to the start of
the class path so that they override any existing dependency that
contains the same classes.

Closes gh-6520
This commit is contained in:
Andy Wilkinson
2016-11-18 15:58:58 +00:00
parent e0bf8ad280
commit 1cd781b242
23 changed files with 509 additions and 69 deletions

View File

@@ -20,7 +20,6 @@ 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;
@@ -86,7 +85,7 @@ public class MockDefinitionTests {
new Class<?>[] { ExampleExtraInterface.class },
Answers.RETURNS_SMART_NULLS, true, MockReset.BEFORE, null);
ExampleService mock = definition.createMock();
MockCreationSettings<?> settings = new MockUtil().getMockSettings(mock);
MockCreationSettings<?> settings = SpringBootMockUtil.getMockSettings(mock);
assertThat(mock).isInstanceOf(ExampleService.class);
assertThat(mock).isInstanceOf(ExampleExtraInterface.class);
assertThat(settings.getMockName().toString()).isEqualTo("name");

View File

@@ -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 org.junit.Test;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.RunWith;
import org.springframework.boot.testutil.ClassPathOverrides;
import org.springframework.boot.testutil.ModifiedClassPathRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for compatibility with Mockito 2.1
*
* @author Andy Wilkinson
*/
@RunWith(ModifiedClassPathRunner.class)
@ClassPathOverrides("org.mockito:mockito-core:2.1.0")
public class Mockito21Tests {
@Test
public void resetMocksTestExecutionListenerTestsWithMockito2() {
runTests(ResetMocksTestExecutionListenerTests.class);
}
@Test
public void spyBeanWithAopProxyTestsWithMockito2() {
runTests(SpyBeanWithAopProxyTests.class);
}
private void runTests(Class<?> testClass) {
Result result = new JUnitCore().run(testClass);
assertThat(result.getFailureCount()).isEqualTo(0);
assertThat(result.getRunCount()).isGreaterThan(0);
}
}

View File

@@ -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 org.junit.Test;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.RunWith;
import org.springframework.boot.testutil.ClassPathOverrides;
import org.springframework.boot.testutil.ModifiedClassPathRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for compatibility with Mockito 2.2
*
* @author Andy Wilkinson
*/
@RunWith(ModifiedClassPathRunner.class)
@ClassPathOverrides("org.mockito:mockito-core:2.2.0")
public class Mockito22Tests {
@Test
public void resetMocksTestExecutionListenerTestsWithMockito2() {
runTests(ResetMocksTestExecutionListenerTests.class);
}
@Test
public void spyBeanWithAopProxyTestsWithMockito2() {
runTests(SpyBeanWithAopProxyTests.class);
}
private void runTests(Class<?> testClass) {
Result result = new JUnitCore().run(testClass);
assertThat(result.getFailureCount()).isEqualTo(0);
assertThat(result.getRunCount()).isGreaterThan(0);
}
}

View File

@@ -19,7 +19,7 @@ package org.springframework.boot.test.mock.mockito;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.internal.util.MockUtil;
import org.mockito.Mockito;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -80,7 +80,8 @@ public class MockitoPostProcessorTests {
context.registerBeanDefinition("beanToBeMocked", factoryBeanDefinition);
context.register(MockedFactoryBean.class);
context.refresh();
assertThat(new MockUtil().isMock(context.getBean("beanToBeMocked"))).isTrue();
assertThat(Mockito.mockingDetails(context.getBean("beanToBeMocked")).isMock())
.isTrue();
}
@Configuration

View File

@@ -20,7 +20,6 @@ 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.ExampleService;
@@ -79,7 +78,7 @@ public class SpyDefinitionTests {
SpyDefinition definition = new SpyDefinition("name", REAL_SERVICE_TYPE,
MockReset.BEFORE, true, null);
RealExampleService spy = definition.createSpy(new RealExampleService("hello"));
MockCreationSettings<?> settings = new MockUtil().getMockSettings(spy);
MockCreationSettings<?> settings = SpringBootMockUtil.getMockSettings(spy);
assertThat(spy).isInstanceOf(ExampleService.class);
assertThat(settings.getMockName().toString()).isEqualTo("name");
assertThat(settings.getDefaultAnswer())