spring integration test无法加载上下文“已存在名为dataSource的另一个资源”

时间:2017-01-28 17:35:53

标签: maven spring-boot jta spring-test atomikos

我正在使用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:已存在另一个资源   name dataSource - 选择一个不同的名称

如果我使用JUnit @Ignore注释跳过此特定测试,一切都会恢复正常。

此行为似乎表明使用@MockBean更改了缓存行为,并且每个测试都尝试创建自己的数据源。我还应该提一下,我正在使用通过 XADataSourceAutoConfiguration 创建的 AtomikosDataSourceBean

如何解决此问题,以便我的集成测试仍然可以使用缓存上下文并同时使用@MockBean

1 个答案:

答案 0 :(得分:1)

嗯,SomeService会以任何方式与您的数据源相关吗?

因为您的上下文被缓存而@MockBean执行以下操作:

  

用于向Spring ApplicationContext添加模拟...在上下文中定义的任何相同类型的现有单个bean将被模拟替换,

  

如果所请求类型的bean不止一个,则必须在字段级别指定限定符元数据:

 @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();
}