SpringBootTest с MockBean не возвращает то, что я ожидаю

Версии:

Java: 1.8
Spring Boot: 1.5.4.RELEASE

Основное приложение:

@SpringBootApplication
public class SpringbootMockitoApplication implements CommandLineRunner {
    @Autowired
    MyCoolService myCoolService;

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

    @Override
    public void run(String... strings) throws Exception {
        System.out.println(myCoolService.talkToMe());
    }
}

Мой сервисный интерфейс:

public interface MyCoolService {
  public String talkToMe();
}

Моя реализация сервиса:

@Service
public class MyCoolServiceImpl implements MyCoolService {

  @Override
  public String talkToMe() {
    return "Epic Win";
  }
}

Мой тестовый класс:

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootMockitoApplicationTests {

    @MockBean
    private MyCoolService myCoolService;

    @Test
    public void test() {
        when(myCoolService.talkToMe()).thenReturn("I am greater than epic");

    }

}

Ожидаемый результат: я больше, чем эпический. Фактический результат: ноль.

Я просто хочу заменить экземпляр bean-компонента в контексте макетом, который вернет «Я больше, чем эпический». Я что-то неправильно настроил здесь?


person Matthew Fontana    schedule 15.06.2017    source источник
comment
Я провел тест с теми же классами, упомянутыми выше, и той же версией Spring Boot, и все работает без проблем. Вы добавили в свой pom.xml зависимости как spring-boot-starter-test, так и spring-boot-test?   -  person Luay Abdulraheem    schedule 16.06.2017


Ответы (1)


Метод run любого CommandLineRunner вызывается как часть выполняемого SpringApplication. Это происходит, когда среда тестирования загружает контекст приложения для ваших тестов. Важно отметить, что это происходит до того, как ваш метод тестирования установит какие-либо ожидания в отношении макета MyCoolService. В результате макет возвращает null при вызове talkToMe().

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

person Andy Wilkinson    schedule 15.06.2017
comment
Эта структура приложения предназначалась для пакетного процесса, который запускается при запуске для тестирования. Было бы разумнее как-то отключить commandLineRunner и воспроизвести логику в бегуне? - person Matthew Fontana; 15.06.2017