我正在使用 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 verify 运行时,多个集成测试失败并显示错误消息
javax.naming.NamingException: Another resource already exists with name dataSource - pick a different name
如果我使用 JUnit @Ignore 注释跳过这个特定的测试,一切都会恢复正常。
此行为似乎表明使用 @MockBean 会更改缓存行为,并且每个测试都尝试创建自己的数据源。我还应该提到我正在使用 AtomikosDataSourceBean 通过 创建XADataSourceAutoConfiguration .
我怎样才能克服这个问题,以便我的集成测试仍然可以使用缓存的上下文并使用
@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 中有数据源,并且您需要访问其中的某些方法,则可以尝试使用 @Mock 并指定需要通过其自己的模拟或 Autowiring 返回的任何对象。
@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();
}
关于maven - spring 集成测试无法加载上下文 "Another resource already exists with name dataSource",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41912757/