Как издеваться над остальными клиентами при тестировании приложения Quarkus?

Quarkus: начало работы unittest описывает, как имитировать внедренные сервисы. Однако при попытке применить это к клиенту с введенным отдыхом это, похоже, не работает.

В моем приложении атрибут класса для вставки определяется следующим образом

  @Inject
  @RestClient
  MyService myService;

В своем тестовом коде я создал фиктивный сервис, подобный этому:

@Alternative()
@Priority(1)
@ApplicationScoped
public class MockMyService extends MyService {

    @Override
    public MyObject myServicemethos() {
        return new MyObject();
    }
}

Обратите внимание, что эта услуга не зарегистрирована и не помечена как RestClient. Выполнение моих юнит-тестов, подобных этому, приводит к следующей ошибке:

org.junit.jupiter.api.extension.TestInstantiationException: TestInstanceFactory [io.quarkus.test.junit.QuarkusTestExtension] failed to instantiate test class [...MyMediatorTest]: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
    [error]: Build step io.quarkus.arc.deployment.ArcAnnotationProcessor#build threw an exception: javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type ...MyService and qualifiers [@RestClient]
    - java member: ...MyMediator#myService
    - declared on CLASS bean [types=[java.lang.Object, ...MyMediator], qualifiers=[@Default, @Any], target=...MyMediator]

    at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.invokeTestInstanceFactory(ClassTestDescriptor.java:314)
  ...

Я, вероятно, могу преодолеть это, добавив дополнительный уровень обслуживания. Но это похоже на движение в неправильном направлении.

Как я могу решить это.

С уважением,

Мысль

5 ответов

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

Согласно документации, вам уже не нужно создавать фиктивный класс https://quarkus.io/guides/getting-started-testing#using-injectmock-with-restclient

но можно использовать как

Класс обслуживания

      @RegisterRestClient(configKey = "country-api")
@ApplicationScoped
public interface MyService

Использование службы

      @Inject
@RestClient
MyService myService;

Насмехайтесь над этим в тесте, как

      @InjectMock
@RestClient 
MyService myService;

Пока все хорошо, но следуя документации https://quarkus.io/guides/rest-client, если вам нужен configKey, вы, вероятно, закончите с

      # Your configuration properties
country-api/mp-rest/url=https://restcountries.eu/rest #
!!country-api/mp-rest/scope=javax.inject.Singleton # /

в вашем файле конфигурации. И тогда ударит по этим вопросам

Возможность использовать InjectMock на MicroProfile RestClient # 8622

Использование InjectMock в MicroProfile RestClient # 9630

Ошибка при попытке протестировать RestClient # 12585

которые говорят: если вы используете configKey с RegisterRestClient, нужно позаботиться о том, чтобы НЕ ИМЕТЬ

      country-api/mp-rest/scope=javax.inject.Singleton # 

в файле конфигурации, который имеет приоритет перед @ApplicationScoped в интерфейсе MyService

Вам не нужен другой уровень косвенности.

Вы можете просто сделать:

@Alternative()
@Priority(1)
@ApplicationScoped
@RestClient
public class MockMyService extends MyService {

    @Override
    public MyObject myServicemethos() {
        return new MyObject();
    }
}

Обратите внимание, что я добавил @RestClient аннотаций.

Используйте аннотацию @Mock

import io.quarkus.test.Mock;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import javax.enterprise.context.ApplicationScoped;

@Mock
@ApplicationScoped
@RestClient
public class MockMyService extends MyService {

    @Override
    public MyObject myServicemethos() {
        return new MyObject();
    }
}

Для выпуска quarkus 1.1.0.Final (последний на момент написания) используйте @RegisterRestClient

@Alternative()
@Priority(1)
@ApplicationScoped
@RegisterRestClient
public class MockMyService extends MyService {
    @Override
    public MyObject myServicemethos() {
        return new MyObject();
    }
}

Из руководства quarkus.io -

По умолчанию аннотацию @InjectMock можно использовать для любого обычного компонента CDI с областью действия (например, @ApplicationScoped, @RequestScoped). Имитацию бинов @Singleton можно выполнить, установивconvertScopesзначение true (например, @InjectMock(convertScopes = true). Это преобразует bean-компонент @Singleton в bean-компонент @ApplicationScoped для теста.

      @InjectMock(convertScopes = true)
@RestClient
MyRestService service;

Работал на меня!!

https://quarkus.io/guides/начало-тестирования

Другие вопросы по тегам