我正在使用
spring-boot 1.4.3中引入的测试注释进行集成测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyServiceIT { }
根据documentation,测试上下文被缓存并重用以加速集成测试.这种行为是我想要的,因为它需要大量的时间来初始化应用程序上下文.我的故障安全插件配置了
<forkCount>1</forkCount>
<reuseForks>true</reuseForks>
允许集成测试在同一进程中运行,以利用应用程序上下文缓存.
最近,我编写了一个使用@MockBean注释的集成测试来模拟某些bean的行为.
@RunWith(SpringRunner.class)
@SpringBootTest
public class AnotherServiceIT {
@MockBean
SomeService service1
}
虽然测试运行良好,但是当通过maven验证运行时,多个集成测试会因错误消息而失败
javax.naming.NamingException: Another resource already exists with
name dataSource – pick a different name
如果我使用JUnit @Ignore注释跳过此特定测试,一切都恢复正常.
此行为似乎表明使用@MockBean更改了缓存行为,并且每个测试都尝试创建自己的数据源.我还要提一下,我正在使用通过XADataSourceAutoConfiguration创建的AtomikosDataSourceBean.
如何克服此问题,以便我的集成测试仍然可以使用缓存上下文并同时使用@MockBean?
最佳答案 嗯,SomeService会以任何方式与您的数据源相关吗?
因为您的上下文被缓存而@MockBean执行以下操作:
used to add mocks to a Spring ApplicationContext … Any existing single bean of the same type defined in the context will be replaced by the mock,
和
If there is more than one bean of the requested type, qualifier metadata must be specified at field level:
@RunWith(SpringRunner.class)
public class ExampleTests {
@MockBean
@Qualifier("example")
private ExampleService service;
编辑:
因此,如果您的SomeService是DataSource的实现,请尝试添加限定符.如果SomeService中包含DataSource,并且您需要访问其中的某些方法,则可以尝试使用@Mock并指定需要通过自己的mock或autowire返回的任何对象.
@Mock
SomeService someService;
@Mock
SomeDependency mockDependency;
@Autowired
OtherDependency realDependency;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
doReturn(mockDependency).when(someService).getSomeDependency();
doReturn(realDependency).when(someService).getOtherDependency();
}