我想知道如何在使用CDI时指定在测试期间应该使用哪个模拟实现。
我知道我可以用@Alternative标记一个模拟实现,但是我需要在beans.xml中定义它。我想有多个模拟(多个对象)。假设我有一个OrderService和一个EmailService。我正在编写一些验收测试,我不希望EmailService发送电子邮件。然后另一组测试是系统测试 - 我想发送电子邮件,但不应该创建真正的订单。
理想的解决方案是为每个测试方法调用指定Alternatives,如下所示:
@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!
}
有可能吗?
答案 0 :(得分:1)
我认为你需要@ Alternative / @ Specialization和Arquillian的组合。 Arquillian为集成测试提供了新的可能性,并允许您通过更改“beans.xml”为每个测试指定不同的替代项。有关具体细节,请参阅this问题。
答案 1 :(得分:1)
CDI-Unit内置了对模拟http://jglue.org/cdi-unit/的支持 只需使用将mock指定为测试类中的producer字段。
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();
}
}
答案 2 :(得分:0)
Roland可能是最可接受的答案,另一种可能的方法是创建一个可移植的扩展,它将读取您在测试或环境中设置的某些属性,以及ProcessAnnotatedType.veto()您不想要的版本。
Arquillian的另一个选择就是不捆绑所有替代方案,并有多个部署可供选择。
答案 3 :(得分: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; }
}