编程语言
首页 > 编程语言> > java – 将测试驱动开发引入遗留代码

java – 将测试驱动开发引入遗留代码

作者:互联网

给定:LegacyControllerClass扩展了MonsterFrameworkClass(一个非常令人讨厌的框架的一部分,人们多年来一直生活在这里). Framework类具有很多魔力,从默认构造函数中的大量逻辑到反射加载类的静态块.

LegacyControllerClass中的许多生命周期方法,它们会改变全局状态. execute()方法是一个千万行,具有你能想到的所有邪恶.

public class LegacyControllerClass extends MonsterFrameworkClass {

   //Life-cycle method
   public void validate(){...}

   //Life-cycle method
   public void preExecute() {...}

   //Life-cycle method
   public void execute() {
       //oodles of legacy code here:
       //    examples: call static methods of 'Util' classes
       //              lots of new X().y(..)
       //              call databases, services
       //              Even call super.execute()!!
       //              More rubbish
       //              More rubbish 
   }
}

好的,现在行动的场景是execute()方法.我正在通过测试驱动一个他们称之为“故事”的项目来向这些穷人介绍测试驱动开发. “故事”涉及向responseProperties添加错误消息,以便视图(jsp)可以将其读取并显示.伪代码类似于:

if (error) {
    Build the error message
    Add the error message into the responseProperties
}

不幸的是,这段代码必须在execute()方法中的垃圾之间进行切换.

我的问题是:我能做的最好的事情是什么?
我可以提出的解决方案是:

>提取两个方法rubbish1()和rubbish2()
>在我的测试代码中将它们存在于任何期望中(例如; – 设置错误标志)
>将我的代码放在rubbish1()和rubbish2()之间

我开始以这种方式实现它,但是MonsterFrameworkClass实际上是我的方式:像静态加载,构造函数魔法加载随机属性文件的ResourceBundle等.

是否有其他方法来处理相同的问题?

Teeny-tiny免责声明:我肯定会购买Michael Feather的“使用传统代码”并将其吞下去,但这似乎是一个低调的结果.

解决方法:

将垃圾重构成方法很好.现在你可以下载Powermock来模拟代码中所有可怕的垃圾.完成模拟后,您可以测试代码.

如果你不为这个怪物添加任何东西,那就更好了.您可以通过为新内容编写自己的类来将您的功能组合成MonstrosityRubbish(或其他).

如果可能的话,最重要的是不要触及任何遗留代码,您可以将代码组合到其中.

所以在代码中:

private MyShinyClass yourShinyObject; // init

public void execute(Param param0) {
    rubbish1();
    yourShinyObject.handleError(param0);
    rubbish2();
}

public class MyShinyClass {

    public void handleError(Param param0) {
        // your code here
    }
}

如果你能设法编写这样的新东西,那么你将只依赖于Param,它可以被模拟/存根,你的代码可以在不设置头发的情况下进行测试.

如果您可以以函数方式编写它,那就更好了,这样您就不必在分离的代码中操作responseProperties:

public void execute(Param param0) {
    rubbish1();
    responseProperties.add(yourShinyObject.fetchErrors(param0));
    rubbish2();
}

public class MyShinyClass {

    public List<HopelessError> fetchErrors(Param param0) {
        // your code here
    }
}

当然,execute()不需要一个参数,你可以传递你想要处理的任何变量/字段Errors().

标签:java,oop,tdd,design-principles
来源: https://codeday.me/bug/20190709/1407653.html