2017-01-28 18 views
1

я использую тест аннотацию, введенную в весенне-ботинке 1.4.3 для моей интеграции тестируетвесной интеграционный тест не сработал контекст «Другой ресурс уже существует с именем DataSource»

@RunWith(SpringRunner.class) 
@SpringBootTest 
public class MyServiceIT { } 

Согласно documentation, контекст теста кэшироваться и повторно использоваться для ускорения интеграционных тестов. Это поведение является тем, что я хочу, поскольку для инициализации контекста приложения требуется значительное количество времени. Мой отказоустойчивый модуль сконфигурирован с

<forkCount>1</forkCount> 
<reuseForks>true</reuseForks> 

, чтобы интеграционные тесты, чтобы работать в том же процессе, чтобы воспользоваться контекстом приложения кэширования.

Недавно я написал тест интеграции, использующий аннотацию @MockBean, чтобы издеваться над поведением некоторых фасоль.

@RunWith(SpringRunner.class) 
@SpringBootTest 
public class AnotherServiceIT { 
    @MockBean 
    SomeService service1 
} 

В то время как тест работает отлично на своем собственном, при запуске через мавена Verify, несколько тестов интеграции завершается с сообщением об ошибке

javax.naming.NamingException: Другой ресурс уже существует с названием DataSource - выберите другое имя

Если я пропущу этот конкретный тест с помощью аннотации JUnit @Ignore, все вернется в норму.

Это поведение указывает на то, что использование @MockBean изменяет поведение кэширования, и каждый тест пытается создать собственный источник данных. Следует также упомянуть, что я использую AtomikosDataSourceBean, созданный с помощью XADataSourceAutoConfiguration.

Как я могу преодолеть эту проблему, поэтому мой интеграционный тест все еще может использовать кешированный контекст и одновременно использовать @MockBean?

+2

Возможно, это проблема с пружинным ботинком? https://github.com/spring-projects/spring-boot/issues/7174 –

+0

Спасибо, что указал мне на проблему. Я использую весеннюю загрузку 1.4.3, и эта проблема должна быть решена. Я сделаю некоторую отладку, чтобы узнать, если это так. – ltfishie

ответ

1

Хм, действительно ли SomeService относится к вашему источнику данных каким-либо образом?

Поскольку ваш контекст кеша и @MockBean выполняет следующие действия:

используется для добавления издевается в Spring ApplicationContext ... Любой существующий единый боб того же типа, определенного в контексте будет заменен издеваться,

и

Если более чем один боб запрашиваемого типа метаданные классификатора должны быть указаны на полевом уровне:

@RunWith(SpringRunner.class) 
public class ExampleTests { 

@MockBean 
@Qualifier("example") 
private ExampleService service; 

Edit:

Так что, если ваш SomeService является реализация DataSource попробовать добавить Qualifier. Если у SomeService есть DataSource, и вам нужно получить доступ к некоторым методам в нем, вы можете попробовать использовать @Mock и указать любые объекты, которые должны быть возвращены либо через их собственный макет, либо autwire.

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