1

Я пытаюсь написать интеграционный тест с использованием Spring Boot, который проверяет логику транзакций в одном из моих контроллеров.Зависимость от контрольных тестов в тестовой программе Spring Boot

Что тест должен сделать, состоит в следующем:

  1. Вводит один из моих контроллеров с помощью @Inject
  2. Замените зависимость электронной почты в контроллерах зависимости с Мок, чтобы избежать фактического отправки по электронной почте в течение интеграционный тест.
  3. Вызов метода контроллера
  4. Убедитесь, что транзакции вызываемого метода должным образом откатываются, когда отправление почты отправляет исключение.

Теперь моя проблема в том, что при запуске теста контроллер вводится в мой тестовый класс, но все его зависимости равны null. Вот моя интеграция тест:

@RunWith(SpringJUnit4ClassRunner.class) 
@IntegrationTest 
@SpringApplicationConfiguration(App.class) 
@WebIntegrationTest 
public MyIntegrationTest() { 

    @Inject MyController controller; 

    @Before 
    public void before() { 
     // replace one particular dependency of controller with a mock 
    } 

    @Test 
    public void testFoo() { ... } 
} 

Благодаря тесту, являющемуся интеграционный тест, который стартует контекст полной весной веб-приложений, я ожидал, что мой контроллер будет иметь всю его зависимость уже autowired, но это, очевидно, не случай, и вместо этого все зависимости установлены равными нулю.

Вопрос: Нужно ли использовать некоторые дополнительные аннотации или установить что-то в моем методе @Before? Или я подхожу к проблеме с совершенно неправильной стороны?

Обновление: Возможно ли протестировать мой Spring MVC Layer без тестирования через HTTP, например, с помощью TestRestTemplate или MockMvc? Но напрямую

ответ

0

Протестируйте с помощью TestRestTemplate вместо того, чтобы вводить сам контроллер. Контроллеры, очевидно, являются весенним бобом, но если вы непосредственно введете его в свой тестовый класс, он не сможет инициализировать контекст.

@RunWith(SpringRunner.class) 
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = ExampleStart.class) 
public class ExampleTest { 
    @Autowired 
    private TestRestTemplate restTemplate; 

    @Test 
    public void exampleTest() { 
     String body = this.restTemplate.getForObject("/", String.class); 
     assertThat(body).isEqualTo("Hello World"); 
    } 
} 

ExampleStart.java -> Весеннее загрузочный класс стартер

@Configuration 
@ComponentScan 
@EnableAutoConfiguration 
public class ExampleStart extends SpringBootServletInitializer { 
    @Override 
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 
     return application.sources(ExampleStart.class); 
    } 

    public static void main(String[] args) { 
     SpringApplication.run(ExampleStart.class, args); 
    } 
} 

Ref: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html

Но если вы хотите, чтобы проверить метод обслуживания, вы можете использовать @Autowired и вызовите методы как обычно.

+0

Если я использую '@ Autowire' или' @ Inject' для ввода класса сервиса в свой тест, то происходит то же самое. Я получаю класс сервиса, введенный в мой тестовый класс, но любая зависимость внутри класса службы, которая обычно вводится с использованием '@ Autowire' или' @ Inject', является 'null'. Например, я вводил «UserService» в свой тестовый класс. У пользовательской службы есть компонент 'PasswordEncoder' и' UserRepository', и оба являются 'null'. – lanoxx

+0

Я обновил ответ, я только что протестировал его, и он работает нормально. Если ваш фактический метод контроллера работает, то тест должен работать. Посмотрите, что вы пропустили. – Avinash

+0

Мой «App.class», который содержит основные методы, значительно проще, он использует только '@ SpringBootApplication' и не имеет метода' configure', как у вас. – lanoxx