Alb*_*Bos 4 java ejb mockito ejb-3.1 jboss-arquillian
我正在开发 Java EE 7(在 Wildfly 9.0.2 上)应用程序,偶然发现了一篇文章http://www.oracle.com/technetwork/articles/java/intondemand-1444614.html。主要是关于:
过早的可扩展性是一些邪恶的根源
这在我遇到的某些情况下是有道理的。我已将一些类更改为无界面视图。实现本身不是问题,但是测试是。
例如我有这两个类。
@Stateless
public class SomeBean {
public String getText()
{
return "Test text";
}
}
Run Code Online (Sandbox Code Playgroud)
和
@Stateless
public class SomeOtherBean {
@Inject
private SomeBean someBean;
public String getText()
{
return someBean.getText();
}
}
Run Code Online (Sandbox Code Playgroud)
我希望以某种方式最好用模拟对象覆盖 someBean 属性。不改变SomeBean和SomeOtherBean类。我尝试了一些示例,但它们不起作用,例如:https :
//github.com/arquillian/arquillian-showcase/tree/master/extensions/autodiscover/src/test/java/org/jboss/arquillian/showcase /扩展/自动发现
有没有人遇到过这个问题并有解决方案?
我最终使用了 2 个解决方案。
解决方案 1:使用 mockito 进行内部或较小的测试
对于测试特定的类 Mockito 非常有用,因为它支持依赖注入。
@RunWith(MockitoJUnitRunner.class)
public class SomeOtherBeanTest {
@Mock
private SomeBean someBean;
@InjectMocks
private SomeOtherBean someOhterBean;
@Before
public void setUp() {
Mockito.when(someBean.getText()).thenReturn("Overwritten!");
}
@Test
public void testGetText() throws Exception {
assertEquals("Overwritten!", someOhterBean.getText());
}
}
Run Code Online (Sandbox Code Playgroud)
解决方案 2:使用 @Produces 和 @Alternatives 来模拟外部服务(例如模拟 OAuth2 服务器)或更大的测试(例如集成测试)
首先,我创建一个新@Alternative注释:
@Alternative
@Stereotype
@Retention(RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})
public @interface CDIMock {}
Run Code Online (Sandbox Code Playgroud)
然后将此作为构造型添加到 arquillianbeans.xml部署中:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="all">
<alternatives>
<stereotype>com.project.CDIMock</stereotype>
</alternatives>
</beans>
Run Code Online (Sandbox Code Playgroud)
之后@Producer在单独的类中创建一个新方法:
public class SomeBeanMockProducer {
@Produces @CDIMock
public static SomeBean produce() {
SomeBean someBean = Mockito.mock(SomeBean.class);
Mockito.when(someBean.getText()).thenReturn("mocked");
return someBean;
}
}
Run Code Online (Sandbox Code Playgroud)
将SomeBeanMockProducer类添加到 arquillian 部署中,您应该让它工作。
此解决方案的替代方案是使用@Specializes和扩展 SomeBean 实现。在我看来,这并没有像@Alternative+ Mocking 解决方案那样给我足够的控制权(@CDIMock在我的例子中)。
例如,假设我SomeBean有调用远程服务器的方法。如果我为此添加一个方法并@override在@Specializes类中忘记了this,它将进行真正的远程调用,而 Mocking 则不会出现这种情况。