4

Quarkus 入门单元测试描述了如何模拟注入的服务。但是,当尝试将其应用于注入的休息客户端时,这似乎不起作用。

在我的应用程序中,要注入的类属性是这样定义的

  @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)
  ...

我可以通过添加一个额外的服务层来克服这个问题。但这感觉就像在朝着错误的方向前进。

我该如何解决这个问题。

亲切的问候,

错误

4

4 回答 4

5

我只是遇到了同样的问题。文档中似乎有更新以及我遇到的一些极端案例,但谷歌搜索首先将我发送到这里,所以我会为未来的读者添加我的调查结果。

根据文档,您已经不需要创建模拟类 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;

到目前为止一切顺利,但如果您需要configKey ,请遵循文档https://quarkus.io/guides/rest-client ,您可能会完成

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

在你的配置文件中。然后会碰到这些问题

能够在 MicroProfile RestClient 上使用 InjectMock #8622

在 MicroProfile RestClient #9630 上使用 InjectMock

尝试测试 RestClient 时出错 #12585

那就是说:如果您将 configKey 与 RegisterRestClient 一起使用,则必须注意不要

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

在配置文件中优先于 MyService 接口上的 @ApplicationScoped

于 2020-12-18T13:21:44.623 回答
5

您不需要另一个级别的间接。

你可以简单地做:

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

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

请注意,我添加了@RestClient注释。

更新

使用它可能更直观,@RegisterRestClient而不是@RestClient在评论和@Tushar 的回答中提到

更新 2

Quarkus 还具有对 CDI bean 的内置模拟支持,请参阅https://quarkus.io/guides/getting-started-testing#further-simplification-with-injectmockhttps://quarkus.io/blog/mocking/

于 2019-05-31T12:59:20.950 回答
1

对于 quarkus 版本 1.1.0.Final(撰写本文时的最新版本),请使用 @RegisterRestClient

@Alternative()
@Priority(1)
@ApplicationScoped
@RegisterRestClient
public class MockMyService extends MyService {
    @Override
    public MyObject myServicemethos() {
        return new MyObject();
    }
}
于 2019-12-24T15:42:37.963 回答
1

使用@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();
    }
}
于 2020-04-21T13:40:42.923 回答