如何模拟改变实例属性状态的void方法

时间:2017-01-06 16:32:36

标签: java unit-testing mocking mockito

在这个类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”)?

3 个答案:

答案 0 :(得分:1)

我建议使用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;
            }
        });

答案 1 :(得分:1)

您可以访问Foo实例并更改namesToFilter Set。

您可以使用Whitebox(导入org.mockito.internal.util.reflection.Whitebox;)。

示例:

Set set = (Set) Whitebox.getInternalState(instance, "namesToFilter");

现在您可以根据需要更改设置。

答案 2 :(得分:0)

UnitTests验证公众可观察行为,而非&#34;代码&#34;。

您的测试与课程Foo的实施高度耦合。但UnitTests的主要目的之一是验证实现中的更改不会无意中更改单元的行为

如果您想更改Foo存储&#34;名称的过滤方式&#34;你还必须改变你的UnitTest。因此,您有风险,即更改UnitTest以验证无意中更改的行为,而无法观察到此情况。

如果您的UnitTest只验证单元与其依赖关系的通信,则类实现中的更改不需要更改UnitTest。因此,您确定UnitTest仍会验证预期的行为。