测试不友好的代码

时间:2011-05-28 11:17:31

标签: unit-testing testing

说我有以下代码,无法修改:

class A {
    public doSomething() {
        // lots of business logic
        data = obtainData();
        // lots of other business logic which depends on data
    }

    private obtainData() {
        // connect to the database
        // send web requests
        // send manned missions to the moon
        // process the obtained data
        return data;
    }
}

测试此类代码的最佳做法是什么?我想确保doSomething()执行它应该执行的操作,但我想为其提供已知数据,而不是在obtainData()内运行代码。

4 个答案:

答案 0 :(得分:0)

查看Moles以帮助您进行棕色地带测试。 C#中的Moles允许您为私有代码和其他人的代码提供自己的实现。

当你有一套完整的测试可以解决这个混乱时,请re-factor来拯救人类。

如果意大利面条代码的发端人在触手可及的范围内,请为我揍他,为什么不呀?

有关最佳做法,请阅读Uncle Bob的清洁代码http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882

总结一下:如果测试中的代码具有外部依赖性,请将它们显式化并可外部配置。

答案 1 :(得分:0)

你没有发布有问题的代码,通常罪魁祸首是构造函数中的新对象创建,静态调用,常量使用以及其他一些。

这个想法是将你的类与它的依赖关系分开。这样做的常见方法是依赖注入。

另外考虑让小班完成非常具体的任务,如果你用句子中的“和”来描述你的班级任务,那就太多了,而且考试难度太大。

有关测试静态和硬编码依赖关系的信息,请参阅this post及其上的所有相关链接。

答案 2 :(得分:0)

设计工作

  1. 确定此课程的职责。
  2. 接下来,提取此类的依赖项。将与bullet#1不对齐的所有方法移动到依赖项中。
  3. e.g。如果此类不负责处理数据库或网络IO,请将它们作为此类的依赖项提取。将它们作为ctor args或method args注入(如果只有一个公共方法需要它)。

    public A(DataRepository repository, WebService service, SpaceStation spaceStation)
    { // cache them as internal fields;}
    

    现在没有必要存根或子类化并覆盖或增加成员可见性以进行测试。

    您的单元测试会创建一个实例

    _testSubject = new A(new Mock<DataRepository>.object, new Mock<WebService>.object, new Mock<SpaceStation>.object);
    

    而您的生产代码将使用上述角色的实际实现。

答案 3 :(得分:-1)

你看过Mocking吗?它可能由您的单元测试框架提供。