如何模拟“Instance<T>”类来测试 quarkus 中一种类型的多个服务?

问题描述 投票:0回答:1

问题:

如何在 quarkus 中使用mockito模拟实例类?

需要使用实例之前的最小示例:

最初我有一个最小的可重现代码,其工作原理如下:

我有一个由 ServiceA 类实现的接口:

public interface ServiceInterface {
    public String getName();
}
@ApplicationScoped
public class ServiceA implements ServiceInterface {

    @Override
    public String getName() {
        return "I am A";
    }
    
}

这已被资源使用:

@Path("/hello")
public class GreetingResource {

    @Inject
    ServiceInterface service;
    

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        StringBuilder stringBuilder = new StringBuilder();

        stringBuilder.append(service.getName());

        return stringBuilder.toString();
    }
}

按预期工作:

我可以编写一个简单的测试来模拟它(

quarkus-junit5-mockito
添加到
pom.xml
):

import static org.mockito.Mockito.when;

@QuarkusTest
class GreetingResourceTest {
    @InjectMock
    ServiceInterface service;

    @Test
    void testHelloEndpoint() {
        when(service.getName()).thenReturn("I am C");

        given()
                .when().get("/hello")
                .then()
                .statusCode(200)
                .body(is("I am C"));
    }

}

显示我的问题的最小示例:

现在我介绍第二项服务:

@ApplicationScoped
public class ServiceB implements ServiceInterface {

    @Override
    public String getName() {
        return "I am B";
    }
    
}

我更改了我的资源以接受这两项服务:

Instance
:


@Path("/hello")
public class GreetingResource {

    @Inject
    Instance<ServiceInterface> services;
    

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        StringBuilder stringBuilder = new StringBuilder();

        for (ServiceInterface service : services) {
            stringBuilder.append(service.getName());
        }

        return stringBuilder.toString();
    }
}

测试它会产生预期的结果:

但是我无法找到重写我的测试的方法。

我的尝试:

例如,解决此问题的一些尝试是:

@QuarkusTest
class GreetingResourceTest {
    @InjectMock
    Instance<ServiceInterface> services;

    @Test
    void testHelloEndpoint() {
        // This is wrong!!!
        when(services.get().getName()).thenReturn("I am C");

        given()
                .when().get("/hello")
                .then()
                .statusCode(200)
                .body(is("I am C"));
    }

}

@QuarkusTest
class GreetingResourceTest {
    @Mock
    Instance<ServiceInterface> services;
    
    @InjectMock
    ServiceInterface service;

    @Test
    void testHelloEndpoint() {
        // This is wrong!!
        when(services.get()).thenReturn(service);
        when(services.get().getName()).thenReturn("I am C");

        given()
                .when().get("/hello")
                .then()
                .statusCode(200)
                .body(is("I am C"));
    }

}

但我无法从返回的异常中找到任何有意义的东西,例如:

org.acme.GreetingResourceTest 类的

字段 jakarta.enterprise.inject.Instance org.acme.GreetingResourceTest.services 不是生产者字段,但使用构造型注释:io.quarkus.test.Mock

java unit-testing mockito quarkus
1个回答
0
投票

我想你想要类似下面的东西。我没有使用过 Quarkus,所以我在这里做了一些假设(包括

Instance::get
返回
List
),但想法是您想要向被测试的类提供
Instance<ServiceInterface>
,并模拟其
get()
方法,然后返回一个模拟
ServiceInterface
,您已在其中设置了适当的期望(或者您甚至可以返回其中一项服务的实际实例)。

@QuarkusTest
class GreetingResourceTest {
    @InjectMock
    Instance<ServiceInterface> services;
    
    @Mock
    ServiceInterface service;

    @Test
    void testHelloEndpoint() {
        when(services.get()).thenReturn(List.of(service));
        when(service.getName()).thenReturn("I am C");

        given()
                .when().get("/hello")
                .then()
                .statusCode(200)
                .body(is("I am C"));
    }
}

对于后一种情况,您只需返回服务的实际实例:

        when(services.get()).thenReturn(List.of(new ServiceB()));
© www.soinside.com 2019 - 2024. All rights reserved.