在这个类Foo中,我有一个初始化使用Set数据结构的过滤器的方法。注意:假设 Foo 类中不允许namesToFilter
的依赖注入
public class Foo {
Set<String> namesToFilter;
public Foo() {
namesToFilter = new HashSet<>();
initialize();
}
void initialize() {
namesToFilter.add("XYZ");
namesToFilter.add("ABC");
}
}
如何在 mockito 中模拟initialize
方法,以便我可以测试其他情况,例如namesToFilter.add("PQR") ?
您可以访问 Foo 实例并更改名称 ToFilter Set。
您可以使用 Whitebox(import org.mockito.internal.util.reflection.Whitebox;)为此。
例:
Set set = (Set) Whitebox.getInternalState(instance, "namesToFilter");
现在,您可以根据需要更改设置。
我会建议使用PowerMock并部分模拟Foo类。
由于测试类应该位于同一包级别,因此应该是可能的。
Foo partialMocked = createMockBuilder(Foo.class)
.addMockedMethod("initialize").createMock();
expect(partialMocked.initialize()).andAnswer(new IAnswer<Void>() {
public Void answer() throws Throwable {
partialMocked.namesToFilter = preInitFilters;
return null;
}
});
UnitTests验证的是公共可观察的行为,而不是"代码"。
您的测试与类Foo
的实现高度耦合。但 UnitTests 的主要目的之一是验证实现中的更改不会无意中更改单元的行为。
如果要更改Foo
存储"要过滤的名称"的方式,还必须更改UnitTest。因此,您有风险更改 UnitTest 以验证无意中更改的行为,而没有任何机会观察到这一点。
如果您的 UnitTest 只验证单元与其依赖项的通信,则类实现中的更改不需要更改 UnitTest。因此,您确定 UnitTest 仍会验证预期的行为。