【问题标题】:unit tests which need CDI container result in java.lang.IllegalStateException: Unable to access CDI需要 CDI 容器的单元测试导致 java.lang.IllegalStateException: Unable to access CDI
【发布时间】:2020-03-15 15:07:28
【问题描述】:

我将 Weld 用于 CDI。

我正在尝试使用 JUnit 5 为服务“A”编写单元测试。 服务A的构造函数是:

@Inject
public A (B b) {this.b = b}

B类构造函数是:

@ApplicationScoped
public class B{ 

private C c;
    public B() {
        c = CDI.current().select(C.class).get();
    }
}

当我在单元测试期间尝试模拟 B 类时,我得到:

java.lang.IllegalStateException: 无法访问 CDI

因为在单元测试期间没有合适的 CDI 容器。

如何解决这个问题?无论如何,Mockito 有吗? (让我们假设替换 CDI.current() 不是一种选择)

这是测试代码的样子:

public class ATest {
private A a;

@WeldSetup
    private WeldInitiator weld = WeldInitiator.from(A.class)
        .addBeans(createBBean()).build();

    private Bean<?> createBBean() {
        return MockBean.builder()
            .types(B.class)
            .scope(ApplicationScoped.class)
            .creating(new B())
            .build();
    }

    @BeforeEach
    void setUpClass() {
        a = weld.select(A.class).get();
     }
}

【问题讨论】:

  • 我不确定我是否看到“没有合适的 CDI 容器。”?您在测试中使用了weld-junit,这意味着如果设置正确,您将运行一个CDI SE 容器。事实上,仅仅使用weld-junit 意味着你不应该需要那个mocked bean(除非你想要一些不同的行为),因为CDI 可以自己构建它。你能详细说明没有那个模拟的 bean 是怎么回事吗?

标签: unit-testing cdi junit5 weld


【解决方案1】:

我总是这样做(CDI 2.0 及更高版本):

private SeContainer container;

@BeforeEach
private void startContainer() {
  SeContainerInitializer initializer = SeContainerInitializer.newInstance();
  // add what you want, disable discovery, whatever
  this.container = initializer.initialize();
}

@AfterEach
private void stopContainer() {
  if (this.container != null) {
    this.container.close();
  }
}

那么任何@Test 都可以访问CDI。

【讨论】:

  • 我得到了“java.lang.IllegalStateException: No valid CDI implementation found”异常。
猜你喜欢
  • 2013-11-02
  • 2016-02-14
  • 2018-04-11
  • 1970-01-01
  • 2023-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-21
相关资源
最近更新 更多