Spring Boot Test с @WebMvcTest не работает на конвейере Atlassian Bitbucket

При локальном запуске некоторых @WebMvcTests проблем не возникает (Spring Boot 1.5.8, gradle 4.6):

@RunWith(SpringRunner.class)
@WebMvcTest(VZNFCController.class)
public class VZNFCControllerTest {

  private VZNFCTagAction action1 = new VZNFCTagAction();
  private VZNFCTagAction action2 = new VZNFCTagAction();

  @Before
  public void setUp(){
      action1.setMessage("message1");
      action2.setMessage("message2");
  }


  @Autowired
  private MockMvc mvc;

  @MockBean
  private VZNFCTagActionRepository actionRepository;

  @MockBean
  private MappingMongoConverter mongoConverter;

  @Test
  @WithMockUser
  public void testGetTagList() throws Exception {

    given(this.actionRepository.findAll())
              .willReturn(Arrays.asList(action1, action2));  
    this.mvc.perform(get("/api/nfc/tags")
            .accept(MediaType.APPLICATION_JSON_UTF8))
            .andExpect(status().isOk());
    }
}

Однако, когда я загружаю в Atlassian Bitbucket и запускаю там ./gradlew test --stacktrace, я получаю следующее:

java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:44)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.

Теперь конвейеры Bibucket используют образ Docker (java: 8). Когда я переключаюсь обратно локально на @SpringBoot и @AutoConfigureMockMvc, я получаю одну и ту же ошибку в обеих средах. Такая же настройка БД в обеих средах (один и тот же образ докера для MongoDB), все одинаково ... Может быть, какой-то порт не отображается при использовании Docker? Я думаю, что создаю запросы сервлетов ...

ИЗМЕНИТЬ

Эмуляция сборки конвейера Bitbucket в контейнере Docker (как предлагается здесь), кажется, что насмешки над MappingMongoConverter и перехода на @SpringBootTest вместе с @AutoConfigureMockMvc достаточно, чтобы запустить его. Таким образом, @WebMvcTest с частично смоделированным контекстом достаточно без контейнера, но он потерпит неудачу внутри контейнера Docker, такого как тот, который присутствует при использовании Bitbucket. Почему?


person thomi    schedule 20.03.2018    source источник


Ответы (1)


Оказывается, не хватало некоторых ключевых компонентов, поскольку аннотация @WebMvc не будет использовать @Components, только то, что необходимо для веб-стека, не включая репозитории, но проблема заключалась в моей конфигурации безопасности, которую я тоже хочу протестировать, и теперь я просто @Import ( вместе с некоторыми другими bean-компонентами, от которых зависит контроллер):

@RunWith(SpringRunner.class)
@WebMvcTest(value = VZNFCController.class)
@Import(value = {VZApiSecurityConfiguration.class, 
                 VZJwtTokenUtils.class, VZProperties.class})
public class VZNFCControllerTest {

  @Autowired
  private MockMvc mvc;

  @MockBean
  private VZNFCTagService tagService;

  /* same as the above... I don't mock out the repository any more */

}

Извлеченный урок состоит в том, что все автоматически настраиваемые тестовые контексты (@WebMvc, @DataMongoTest и т. Д.) Ускоряют ваши тесты (что хорошо, потому что я плачу минуты сборки на битбакете). Но вам нужно действительно знать, что нужно для запуска этой части вашего приложения. Это заставило меня по-настоящему смоделировать службу, чтобы сосредоточиться на контроллере, а затем написать еще несколько тестов для части DAO моего приложения. Думаю, это хорошо.

person thomi    schedule 02.04.2018