шпион mockito не работает на фабричном методе - PullRequest
0 голосов
/ 13 июня 2019

У меня есть Springboot, для которого я пишу юнит-тест.Есть factoryBean, из которого я получаю сервисный объект во время выполнения.Я хочу проверить, что конкретный метод для этого объекта службы вызывается.Вот код приложения

@Component
public class AppClient {

    @Autowired
    ServiceFactory factory

    Service secretService

    @postContruct
    public void init(){
        this.secretService=factory.get("secret");
    }

    public void process(Map<String, Object> param){
        for (String key: param.keySet()){
            if (key.equals("foobar")){
                restService.handle(param.get(key));
            }
        }
    }
}

Вот мой тестовый модуль

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

  @Autowired
  AppClient appClient;

  @SpyBean
  ServiceFactory factory;

  Service secretService;

  @Before
  public void init(){
    this.secretService=Mockito.spy(factory.get("secret"));
  }

  @Test
  public void testProcess() {
    Object obj = new MyDummyObject();
    Map<String, Object> params = new HashMap<>();
    params.put("foobar", obj);
    appClient.process(params);
    Mockito.verify(secretService).handle(obj);
  }
}

Тест не пройден, и когда я запускаю отладчик, я вижу, что дескриптор вызывается.так что же здесь не так?

EDIT

@MockBean
ServiceFactory factory;

@Mock
Service secretService

@Before
public void init(){
  Mockito.when(factory.get(eq("secret"))).thenReturn(secretService);
}

с этим изменением фабричный бин высмеивается, но SecretService внутри AppClient имеет значение null.то есть secretService не заглушается. протестировано с помощью отладчика.

1 Ответ

1 голос
/ 16 июня 2019

Обратный вызов PostConstruct выполняется до того, как приложение Spring полностью запустится, и перед тем, как ваш тестовый класс сделает некоторые приготовления на макете фабрики.Невозможно объявить ожидания Mockito when().then() в коде, который выполняется в обратном вызове PostConstruct.

Я могу предложить вам сделать инжекцию на основе конструктора в bean-компоненте AppClient:

@Component
public class AppClient {

    private final ServiceFactory factory

    @Autowired
    public AppClient(ServiceFactory factory){
       this.factory = factory;
    }

    ...
}

и проверить это как простой модульный тест.Создав вручную экземпляр AppClient, внедрив макет фабрики, выполните метод init и проверьте все, что вам нужно:

@Test
void initTest(){
  when(factory.get(..)).thenReturn(..);

  AppClient client = new AppClient(factory);
  client.init();

  verify(..)
}
...