1

在主代码中说,你有这样的东西:

MyClass.java

public class MyClass {
    public List<Obj1> create(List<ObjA> list) {
        return (new MyClassCreator()).create(list);
    }
    // Similar methods for other CRUD operations
}

MyClassCreator.java

public class MyClassCreator {
    Obj1Maker obj1Maker = new Obj1Maker();

    public List<Obj1> create(List<ObjA> list) {
        List<Obj1> converted = new List<Obj1>();
        for(ObjA objA : list)
            converted.add(obj1Maker.convert(objA));
        return converted;
    }
}

Obj1Maker.java

public class Obj1Maker {
    public Obj1 convert(ObjA objA) {
        Obj1 obj1 = new Obj1();
        obj1.setProp(formatObjAProperty(objA));
        return obj1;
    }

    private String formatObjAProperty(ObjA objA) { 
        // get objA prop and do some manipulation on it
    }
}

假设 Obj1Maker 的单元测试已经完成,并且涉及一个模拟makeObjAMock()复杂对象 A的方法。

我的问题:

  1. 对于 MyClassCreator 的单元测试,我将如何测试create(List<ObjA> list)?该方法真正所做的只是将转换委托给ObjAtoObj1并在循环中运行它。转换本身已经过测试。如果我要创建一个列表ObjA并测试我返回的列表中的每个对象Obj1,我将不得不复制makeObjAMock()到 MyClassCreator 的单元测试中。显然,这将是重复的代码,所以使用verify()足以确保 create(List list) 有效吗?

  2. 对于 MyClass 的单元测试,同样,它的create(List<ObjA>)方法只是将操作委托给 MyClassCreator。我真的需要用完整的测试用例来测试它,还是应该只验证 MyClassCreator 的create方法是否被调用?

  3. 在 Obj1Maker 的单元测试中,我通过做来检查属性 Obj1 和 ObjA 是否相互对应assertEquals(obj1.getProp(), formatObjAProperty(objA))。但是,这意味着我必须将formatObjAPropertyObj1Maker 类中的私有方法的代码复制到其单元测试中。在这种情况下如何防止代码重复?我不想让这个方法公开/受保护,这样我就可以在单元测试中使用它。在这种情况下可以接受重复吗?

谢谢,对冗长的问题感到抱歉。

4

1 回答 1

0

我的意见就在这里。选择要测试的方法是一件很难的事情。

您必须考虑 a)您是否满足您的要求,以及 b)当将来有人愚蠢地更改代码时会出现什么问题。(其实傻子可能就是你。我们都有不好的日子。)

我想说,编写新代码来验证两个对象具有两种格式的相同数据是个好主意。可能没有理由从私有方法复制代码并且复制代码是一个坏主意。请记住,您正在验证需求。因此,如果原始字符串表示“2013 年 6 月 30 日”,而重新格式化的字符串表示“2013 年 6 月 30 日”,我将硬编码检查:

assertEquals("Wrong answer", "June 30th 2013", obj.getProp());

为边缘情况和错误添加更多断言。(在我的例子中,使用“2/30/13”和“2/29/12”和“12/1/14”来检查非法日期、闰年,它可能是“第一个”而不是“第一个”。 )

在对 create 方法的测试中,我可能会选择简单的错误并验证返回的数组是否与传入的数组具有相同的数字。我传入的数组将有两个相同的元素和一些不同的元素。我只是检查相同的返回相同而不同的返回不相同。为什么?因为我们已经知道格式化程序的工作原理。

我不会测试构造函数,但会确保一些测试运行其中的代码。确保大多数代码实际上在测试中运行以捕获诸如您错过的空指针之类的愚蠢错误是很好的。

平衡点就是您要寻找的。

足够的测试,测试足够多的不同的东西,让代码工作感觉良好。

足够的测试,测试明显的东西,将来会发现愚蠢的变化。

没有那么多测试需要永远运行,所有开发人员(包括您)都会推迟运行它们,因为他们不想在运行时等待或失去思路。

平衡!

于 2013-08-07T18:24:52.867 回答