Mat*_*mer 10 java unit-testing mockito cdi
我正在使用WELD-SE进行依赖注入的Java SE环境中进行编程.因此,类的依赖关系看起来像这样:
public class ProductionCodeClass {
@Inject
private DependencyClass dependency;
}
Run Code Online (Sandbox Code Playgroud)
在为这个类编写单元测试时,我正在创建一个模拟器DependencyClass,因为我不想为我运行的每个测试启动一个完整的CDI环境,我手动"注入"模拟:
import static TestSupport.setField;
import static org.mockito.Mockito.*;
public class ProductionCodeClassTest {
@Before
public void setUp() {
mockedDependency = mock(DependencyClass.class);
testedInstance = new ProductionCodeClass();
setField(testedInstance, "dependency", mockedDependency);
}
}
Run Code Online (Sandbox Code Playgroud)
setField()我使用我在测试中使用的工具在类中编写的静态导入方法:
public class TestSupport {
public static void setField(
final Object instance,
final String field,
final Object value) {
try {
for (Class classIterator = instance.getClass();
classIterator != null;
classIterator = classIterator.getSuperclass()) {
try {
final Field declaredField =
classIterator.getDeclaredField(field);
declaredField.setAccessible(true);
declaredField.set(instance, value);
return;
} catch (final NoSuchFieldException nsfe) {
// ignored, we'll try the parent
}
}
throw new NoSuchFieldException(
String.format(
"Field '%s' not found in %s",
field,
instance));
} catch (final RuntimeException re) {
throw re;
} catch (final Exception ex) {
throw new RuntimeException(ex);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我不喜欢这个解决方案的是,在任何新项目中我都需要这个帮助器.我已将它打包为Maven项目,我可以将其作为测试依赖项添加到我的项目中.
但是,在我失踪的其他一些公共图书馆中是否有现成的东西?对我这样做的一般意见吗?
Mag*_*lex 17
Mockito支持开箱即用:
public class ProductionCodeClassTest {
@Mock
private DependencyClass dependency;
@InjectMocks
private ProductionCodeClass testedInstance;
@Before
public void setUp() {
testedInstance = new ProductionCodeClass();
MockitoAnnotations.initMocks(this);
}
}
Run Code Online (Sandbox Code Playgroud)
@InjectMocks注释将触发注入在测试类中模拟的类或接口,在这种情况下DependencyClass:
Mockito尝试按类型注入(在案例类型相同的情况下使用名称).当注入失败时,Mockito不会抛出任何东西 - 您必须手动满足依赖关系.
在这里,我也使用@Mock注释而不是调用mock().你仍然可以使用mock(),但我更喜欢使用注释.
作为旁注,有可用的反射工具,它支持您实现的功能TestSupport.一个这样的例子是ReflectionTestUtils.
也许更好的是使用构造函数注入:
public class ProductionCodeClass {
private final DependencyClass dependency;
@Inject
public ProductionCodeClass(DependencyClass dependency) {
this.dependency = dependency;
}
}
Run Code Online (Sandbox Code Playgroud)
这里的主要优点是很清楚类所依赖的类,并且在不提供所有依赖项的情况下无法轻松构建它.此外,它允许注入的类是最终的.
通过这样做,@InjectMocks没有必要.相反,只需通过将mock作为参数提供给构造函数来创建类:
public class ProductionCodeClassTest {
@Mock
private DependencyClass dependency;
private ProductionCodeClass testedInstance;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
testedInstance = new ProductionCodeClass(dependency);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11715 次 |
| 最近记录: |