CDI @Alternative-每个测试用例选择替代项

问题描述 投票:3回答:4

我想知道如何指定在使用CDI的测试过程中应使用哪种模拟实现。

我知道我可以用@Alternative标记一个模拟实现,但随后需要在beans.xml中对其进行定义。我想拥有多个模拟对象(用于多个对象)。可以说我有一个OrderService和一个EmailService。我正在编写一些验收测试,我不希望EmailService发送电子邮件。然后另一组测试是系统测试-我确实要发送电子邮件,但不应创建真实订单。

理想的解决方案是为每个测试方法调用指定替代项,如下所示:

@BeforeMethod
public void before(){
  // in this test suite we're using mock email service
  addAlternative(MockEmailService.class);
}
@Test
public void testMyStuff(){
  issueAnOrder(); // and verify that it worked. no emails sent!
}

有可能吗?

java testing cdi
4个回答
1
投票

我认为您需要结合使用@ Alternative / @ Specialisation和Arquillian。 Arquillian为集成测试提供了新的可能性,并使您可以通过更改“ beans.xml”为每个测试指定不同的替代方案。有关详细信息,请参阅this问题。


2
投票

CDI-Unit内置了对模拟http://jglue.org/cdi-unit/的支持只需在测试类中使用指定的模拟作为生产者字段即可。

class Starship {

  @Inject
  Engine engine; //This will be mocked

  void start() {
    engine.start();
  }
}


@RunWith(CdiRunner.class)
class TestStarship {

  @Inject
  Starship starship;

  @Produces
  @Mock // Mockito will create a mock for us.
  Engine engine;

  @Test
  public void testStart() {
    starship.start();

    // Verify that the mocks start method is called at least once.
    Mockito.verify(engine, Mockito.atLeastOnce()).start();
  }
}

0
投票

罗兰可能是最好的可接受的答案,另一种可能的方法是创建一个可移植的扩展,该扩展将读取您在测试或环境中设置的某些属性,并读取不需要的版本的ProcessAnnotatedType.veto()。

Arquillian的另一个选择就是不捆绑所有选择,并选择多个部署。


0
投票

您可以通过在测试中以编程方式配置CDI容器来实现。

为此,在测试类的CDI容器上设置disableDiscoveryMode(),将测试的必要类添加到容器中(至少将您的测试主题替换为类),然后添加替换类作为替代。

下面是一个例子。 Greeter是我的测试主题,Greeting是默认的bean,GreetingAlt是替代的。

测试类:

public class GreeterTest {

    private Greeter greeter;

    @Before
    public void setUp() {
        try (WeldContainer container = new Weld().disableDiscovery()
                .addBeanClass(Greeter.class)
                .addBeanClass(Greeting.class)
                .addBeanClass(GreetingAlt.class)
                .addAlternative(GreetingAlt.class).initialize()) {
            greeter = container.select(Greeter.class).get();
        }
    }

    @Test
    public void hiShouldContainMock() {
        assertThat(greeter.hi(), containsString("Mock"));
    }
}

主要类别:

public class Greeter {
    @Inject IGreeting iGreeting;
    public String hi() { return iGreeting.greet("John"); }
}
@Default
public class Greeting implements IGreeting {
    @Override public String greet(String name) { return "Hello " + name; }
}
@Alternative
public class AltGreeting implements IGreeting {
    @Override public String greet(String name) { return "Mock " + name; }
}
© www.soinside.com 2019 - 2024. All rights reserved.