0

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

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

我确实想出了如何:

  • 用测试实现(单独的类)替换一个 bean:通过用@Priority(1)and注释测试实现类并@Alternative通过用@AddBean(MyBeanTestImpl.class).
    • 但我不能创建一个模拟(使用 Mockito)作为一个单独的类。
  • 生产一个mock(MyBean.class):通过创建一个生产者方法并使用以下注释@Produces
    • 但它与真正的 bean 冲突并给出:“WELD-001409:类型不明确的依赖项......”
    • 当我也用@Alternative它来注释它时,它被简单地忽略了。
    • 我不能用 注释它@Priority(1),因为这个注释只能应用于类型和参数。

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

4

1 回答 1

1

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

待测类

@ApplicationScoped
public class SomeService {
    private ExternalService externalService;

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

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

测试班

@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();
    }
}

完成上述操作后,您可以扩展我们创建的帮助程序类,而不是 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);
        }

      }
于 2021-12-16T10:19:25.263 回答