【问题标题】:TDD approach for complex function复杂函数的 TDD 方法
【发布时间】:2010-05-05 17:56:44
【问题描述】:

我在一个类中有一个方法,它们有几个不同的结果(基于事件响应等)。但这是供其他应用程序使用的单个原子函数。

我已将构成此功能的主要功能块分解为不同的功能,并成功地采用了测试驱动开发方法来处理每个元素的功能。然而,这些元素不会暴露给其他应用程序使用。

所以我的问题是我如何/应该如何轻松地使用 TDD 风格的解决方案来验证应该调用的单个方法是否正确运行,而无需在测试中进行大量重复或每次测试都需要大量设置?

我已经考虑/考虑将功能块移动到不同的类中,并使用 Mocking 来模拟所用函数的响应,但感觉不对,并且各个方法需要写入主类中的变量(感觉真的是希思·罗宾逊)。

代码大致是这样的(我删除了很多参数以使事情更清晰,还有一些不相关的代码)。

public void MethodToTest(string parameter)
{
    IResponse x = null;

    if (function1(parameter))
    {

        if (!function2(parameter,out x))
        {
            function3(parameter, out x);
        }
    }

    // ...
    // more bits of code here
    // ...

    if (x != null)
    {
        x.Success();
    }
}

【问题讨论】:

  • 如果一个方法影响了应用程序的一部分而没有给出任何类型的返回/响应,如果它失败与否,有人可能会说设计有问题。我会重构方法,首先创建一个测试方法! (您可以在这里阅读有关它的信息:blog.smartit.se/2010/04/23/…)。如果该方法返回 void 并且没有抛出任何异常,那么它可能有效.. 对吗?可能是错误的设计。然而,这只是一个指针,而不是一个答案:)

标签: c# .net unit-testing tdd


【解决方案1】:

我认为通过避免使用 out 关键字并重新编写代码以便函数检查响应的某些条件,或修改响应,但不能同时修改两者,我认为您可以让您的生活更轻松。比如:

public void MethodToTest(string parameter)
{
    IResponse x = null;

    if (function1(parameter))
    {

        if (!function2Check(parameter, x))
        {
            x = function2Transform(parameter, x);
            x = function3(parameter, x);
        }
    }

    // ...
    // more bits of code here
    // ...

    if (x != null)
    {
        x.Success();
    }
}

这样您就可以更轻松地开始拆分并重新组合大型方法的各个部分,最后您应该有类似的东西:

public void MethodToTest(string parameter)
{
    IResponse x = ResponseBuilder.BuildResponse(parameter);

    if (x != null)
    {
        x.Success();
    }
}

... BuildResponse 是您当前所有测试所在的位置,并且 MethodToTest 的测试现在应该相当容易模拟 ResponseBuilder。

【讨论】:

    【解决方案2】:

    您最好的选择确实是模拟 function1,2,3 等。如果您无法将函数移动到单独的类,您可以考虑使用嵌套类将函数移动到,它们能够访问外部数据班级。之后,您应该能够使用模拟而不是嵌套类进行测试。

    更新:通过查看您的示例代码,我认为您可以通过研究访问者模式和测试方法获得一些灵感,这可能是合适的。

    【讨论】:

      【解决方案3】:

      在这种情况下,我认为您只需模拟您提到的方法调用。

      通常,您会先编写测试,然后以某种方式编写方法,以使所有测试都通过。我注意到,当你这样做时,编写的代码非常干净且切中要害。此外,每个类都非常好,只有一个可以轻松测试的职责。

      我不知道出了什么问题,但 smell 不对,我认为可能有更优雅的方式来做你正在做的事情。

      【讨论】:

        【解决方案4】:

        恕我直言,您有几个选择:

        1. 将内部函数分解为不同的类,以便您可以模拟它们并验证它们是否被调用。 (你已经提到过)
        2. 听起来您创建的其他方法是私有方法,并且这是这些方法的唯一公共接口。如果是这样,你应该通过这个函数运行那些测试用例,并验证结果(你说那些私有方法修改了类的变量)而不是测试私有方法。如果那太痛苦了,那么我会考虑重新设计您的设计。

        在我看来,这门课试图做的不止一件事。例如,第一个函数不返回响应,但其他两个函数返回。在您的描述中,您说该功能很复杂并且需要很多参数。这些都是您需要重构设计的迹象。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-08-09
          • 1970-01-01
          • 2012-05-14
          • 2016-06-08
          • 1970-01-01
          • 1970-01-01
          • 2011-07-14
          相关资源
          最近更新 更多