"Bypassing" Quarkus 单元测试中的模拟

"Bypassing" a mock in Quarkus unit testing

我有一个 Quarkus 项目,其中我将大部分业务逻辑放在服务中,也就是使用 @ApplicationScoped 注释的可注入 bean,所有 CRUD 操作都在其中进行。在 JAX-RS 资源文件本身中,大部分逻辑只是验证,通常使用整个验证 bean。这意味着我们需要在测试资源时模拟注入的服务,以防止单元测试本质上变成集成测试。我们这样做具有这样的结构(示例项目);

文件 MockGreetingService.java 依次如下所示:

import io.quarkus.test.Mock;

import javax.enterprise.context.ApplicationScoped;

@Mock
@ApplicationScoped
public class MockGreetingService extends GreetingService {

    @Override
    public String sayHello(String name) {
        return String.format("Hello %s, your id is %s", name, "1234");
    }
}

我们的实际项目比这复杂一点,无论输入如何,模拟总是 return 我们的 DTO classes,但原理与上述相同。它们可以完美地用于我们的 JAX-RS 资源测试。但是,尝试测试实际的服务 bean 本身意味着此设置存在问题。我构建了一个服务测试,它使用与以下代码相同的注释和流程:

import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import javax.inject.Inject;

@QuarkusTest
public class GreetingServiceTest {

    @Inject
    GreetingService greetingService;

    @Test
    void checkReturnsHello () {

        String result = greetingService.sayHello();
        System.out.println(result);
        Assertions.assertEquals("hello Martin! Your country is Italy", result);
    }
}

通过上面 class 中的依赖注入,我们在资源测试中没有这样做,我希望 Quarkus 理解我们想在此测试中使用原始服务。我真傻。一个简单的日志显示,在上面的后一个测试中,模拟服务方法确实仍然 运行。

现在我想知道 - 这是否是一种为后一个测试禁用模拟的方法?最好不必修改或删除模拟 classes,尽管我意识到这可能无法像我想象的那样实现。提前致谢!

听起来像是限定符的用例,它使您能够拥有不同的实现 bean,并在注入点选择您喜欢的 bean 类型: https://jakarta.ee/specifications/cdi/2.0/cdi-spec-2.0.html#qualifiers

作为替代方案,您也可以决定自己实例化您的服务,而不以任何方式使用 cdi。