在 Helidon 测试中用模拟替换 bean

Replace a bean by a mock in Helidon test

我有一个 Helidon 应用程序,我想测试它的(部分)。

我的测试用 @HelidonTest 注释,现在我想用一个 mock 替换一个 bean(并配置这个 mock,使用找到的所有其他 bean,但注入 mock)。

我确实想出了如何:

知道如何用模拟替换一个 bean 吗?

我尝试了 setter 注入来手动注入模拟 bean。

Class 测试中

@ApplicationScoped
public class SomeService {
    private ExternalService externalService;

    @Inject
    public void setExternalService(ExternalService externalService) {
        this.externalService = externalService;
    }

    public String doSomething() {
        return externalService.getData();
    }
}

测试Class

@HelidonTest
class SomeServiceTest {
    @Inject
    private SomeService someService;

    private ExternalService externalService;

    @BeforeEach
    void setUp() {
        externalService = Mockito.mock(ExternalService.class);
        someService.setExternalService(externalService);
    }

    @Test
    void doSomething() {
        Mockito.when(externalService.getData())
                .thenReturn("Mock data");
        String actual = someService.doSomething();
        Assertions.assertEquals("Mock data", actual);
    }
}

还有一些方法可以通过模拟构造函数来模拟整个 bean。为此,我们必须使用@Observes 注释

@HelidonTest
public abstract class HelidonTestHelper {


    private MockedConstruction<ExternalService> mockedConstruction;

    void init(@Priority(1) @Observes @Initialized(ApplicationScoped.class) ContainerInitialized containerInitialized) {
        mockedConstruction = Mockito.mockConstruction(ExternalService.class);
        //mock common beans here. This will be executed once application scope is loaded.
    }
    void onStop(@Priority(1) @Observes @Destroyed(ApplicationScoped.class) ContainerShutdown containerShutdown) {
        //do cleanup here if needed.
        mockedConstruction.closeOnDemand();
    }
}

完成上述操作后,您可以扩展我们创建的助手 class,而不是 helidon 测试。

    class SomeServiceTest extends HelidonTestHelper {
        @Inject
        private SomeService someService;
    
        @Inject //this will be a mock 
        private ExternalService externalService;
        
        @Test
        void doSomething() {
            Mockito.when(externalService.getData())
                    .thenReturn("Mock data");
            String actual = someService.doSomething();
            Assertions.assertEquals("Mock data", actual);
        }

      }