TDD方法用于复杂功能

时间:2010-05-05 17:56:44

标签: c# .net unit-testing tdd

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

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

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

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

代码大致看起来像这样(我已经删除了很多参数以使事情更清晰,并且有一些不相关的代码)。

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();
    }
}

4 个答案:

答案 0 :(得分: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。

答案 1 :(得分:0)

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

  1. 将内部函数分解为不同的类,以便您可以模拟它们并验证它们是否被调用。 (你已经提到过)
  2. 听起来你创建的其他方法都是私有方法,而这是这些方法的唯一公共接口。如果是这样,您应该通过此函数运行这些测试用例,并验证结果(您说这些私有方法修改了类的变量)而不是测试私有方法。如果这太痛苦了,那么我会考虑重新设计你的设计。
  3. 在我看来,这堂课试图做的不止一件事。例如,第一个函数不返回响应,但另外两个函数返回响应。在您的描述中,您说功能很复杂并且需要很多参数。这些都是你需要重构设计的迹象。

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

在这种情况下,我认为你只会像你提到的那样模拟方法调用。

通常,您首先编写测试,然后以某种方式编写方法,以便所有测试都通过。我注意到,当你这样做的时候,编写的代码非常干净而且非常重要。此外,每个班级都非常擅长于只有一个可以轻松测试的责任。

我不知道什么是错的,但有些事情没有smell正确,而且我认为可能有一种更优雅的方式来做你正在做的事情。