Тестирование @Postconstruct с Mockito

Почему, когда я внедряю макеты через Mockito, мой метод @Postconstruckt не вызывается?

@Service
public class MyService {
    public MyService() {
        System.out.println("CONSTRUKTOR");
    }

    @PostConstruct
    public void init() {
        System.out.println("POST CONSTRUCT");
    }

@RunWith(MockitoJUnitRunner.class)
public class Mockito1 {

    @InjectMocks
    private MyService service;

    @Before
    public void init() {
    }

Выход: Только: CONSTRUKTOR


person Jan Testowy    schedule 25.09.2018    source источник
comment
Что вы хотите получить от этого макета? Вы используете этот сервис где-то еще или действительно тестируете сервис?   -  person Makoto    schedule 25.09.2018
comment
Мне просто интересно, как mockito относится к @postconstruct. Я ожидаю что-то вроде: CONSTRUCTOR, POST CONSTRUCT   -  person Jan Testowy    schedule 25.09.2018
comment
Зачем ему что-то делать с этим? Вы издеваетесь (например, подделываете) управляемые Spring взаимодействия с этим объектом, поэтому конструкция Spring @PostConstruct даже не будет применяться. Итак, еще раз, какова ваша цель с этим макетом? Вы хотите протестировать этот сервис или использовать макет своего сервиса где-то еще?   -  person Makoto    schedule 25.09.2018


Ответы (3)


Потому что PostConstruct — это всего лишь концепция spring. Но вы можете вызвать postConstruct вручную.

@Before
public void prepare() {
    MockitoAnnotations.initMocks(this);
    this.service.init(); //your Injected bean
}

person Vadim Yemelyanov    schedule 25.09.2018
comment
@PostConstruct — это не только концепция Spring, это даже не аннотация Spring. - person M. Deinum; 25.09.2018

Я немного изменил ваш сервис, добавив метод foo:

@Service
public class MyService {
    public MyService() {
        System.out.println("CONSTRUKTOR");
    }

    @PostConstruct
    public void init() {
        System.out.println("POST CONSTRUCT");
    }

    public String foo() {
        return "bar";
    }
}

Если вы хотите получить поведение, которое вы описали, есть как минимум две возможности:

  1. @RunWith(SpringJUnit4ClassRunner.class) + @Autowired - эта комбинация позволит получить в тесте обычный сервис

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = MyService.class)
    public class Mockito1 {
    
        @Autowired
        private MyService service;
    
        @Before
        public void init() {
        }
    
        @Test
        public void name() throws Exception {
            System.out.println(service.foo());
        }
    }
    

Этот код напечатает:

CONSTRUKTOR
POST CONSTRUCT
bar
  1. @RunWith(SpringJUnit4ClassRunner.class) + @SpyBean — эта комбинация позволит вам получить сервис в своем тесте и изменить его поведение с помощью Mockito.

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = MyService.class)
    public class Mockito1 {
    
        @SpyBean
        private MyService service;
    
        @Before
        public void init() {
        }
    
        @Test
        public void name() throws Exception {
            System.out.println(service.foo());
            Mockito.when(service.foo()).thenReturn("FOO");
            System.out.println(service.foo());
        }
    }
    

Этот код напечатает:

CONSTRUKTOR
POST CONSTRUCT
bar
FOO
person Aleksandr Semyannikov    schedule 25.09.2018

@PostConstruct — это аннотация, определенная JSR 250, и она будет игнорироваться в вашем текущем тесте, потому что вы используете @RunWith(MockitoJUnitRunner.class), т. е. бегун JUnit, который не знает об этой аннотации. Если вы пишете модульные тесты, они должны быть простыми и просто проверять бизнес-логику вашего приложения, но если вы хотите написать интеграционные тесты, которые используют некоторый сторонний код, способный обрабатывать такого рода аннотации, например, Spring . Затем вы можете аннотировать свой тестовый класс следующими аннотациями:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {AppConfig.class})
person Diego Marin Santos    schedule 25.09.2018