maven – spring集成测试无法加载上下文“另一个资源已存在,名称为dataSource”

我正在使用
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();
}
点赞