Java - 在类

时间:2017-05-23 13:05:16

标签: java mocking


我正在寻找一种方法来测试处理数据的类中的数据,然后以尽可能干净和便携的方式上传数据。因此,我不想诉诸于公开获取函数,以避免任何能够访问此数据。为了保持便携性,我想避免使用测试数据库,以便在任何情况下都可以运行这些测试。

Class Foo {     
    private int a;
    private int b;
    private int c;
    private DBSaver dbSaver;

    public Foo(DBSaver dbSaver) {       
        this.dbSaver = dbSaver;
    }

    public void processData() {           
        processData();
        saveToDB();
    }

    private void workNumbers() {     
        a = 1;
        b = 2;
        c = a + b;
    }

    private void saveToDB() {           
        List<Integer> list = new ArrayList<>();
        list.add(a); list.add(b); list.add(c);
        dbSaver.save(list);
    }
}

测试类:

class FooTest {       
    @Mock
    DBSaver dbSaver;
    @Mock
    Foo foo;

    @Test
    private void test() {when(dbSaver.save(any(ArrayList<>.class))).then(returnsFirstArg());
        foo = new Foo(dbSaver);
        Mockito.doThrow(new Exception() {
                //Now I would like to get a, b and c so I can ensure that they have the proper values.
            }
            ).when(foo).processData();
    }
}

Here是代码的pastebin版本]()。

workNumbers()将正常执行,并且由于save()函数已被模拟为什么都不做,因此该代码不会做太严重的事情。

我想问一下现在是否有办法通过模拟抛出的异常,以列表形式返回a,b和c值。问题是通过FooTest中的模拟实例访问Foo中的私有值。

1 个答案:

答案 0 :(得分:1)

您正在通过模拟错误进行单元测试。有这个没有意义:

@Mock
Foo foo;

Foo是你的“被测试的课程”。你做想要嘲笑它。如果有的话,您可能需要在此处创建间谍,以便执行 partial mocking

在您的情况下,您无需访问这些私人字段。你知道,关键是你的代码会调用:

dbSaver.save(list);

在某个时候。含义:您可以使用Mockitoy 验证模拟 dbSaver对象上调用save()时传递特定列表。

这就是重点:你有那个模拟的dbSaver实例,所以你在 total 控制那里发生了什么。如上所述,您可以验证使用特定参数调用其方法;或者您甚至可以使用ArgumentCaptor来访问传递给该方法调用的列表。

然后,您只需确保该列表包含预期的内容(这将是您所测试的类中的三个值!)。看到 here例如如何做到这一点。

最后:尤其是“异常”部分确实是错误的。这里不需要生成异常。您只需将模拟的dbSaver推送到Foo的实例中,就可以在该Foo实例上调用方法;然后你检查预期的结果。而已;其他任何东西都是(无用的)过度复杂的东西。