【问题标题】:How can I write TDD code from the code below?如何从下面的代码中编写 TDD 代码?
【发布时间】:2014-04-05 17:24:33
【问题描述】:
static void Main(string[] args)
{
    for (int i =1 ; i<=100;i++)
    {
        Console.WriteLine(i.ToString());

        if (i % 3 == 0)
            Console.WriteLine("HOON");
        if (i % 5 == 0)
            Console.WriteLine("Group");
        if (i % 3 == 0 && i % 5 == 0)
            Console.WriteLine("HOON Group");
    }
}

我需要使用上面的代码编写测试代码。

共有三个特点。 有人可以给我建议吗?

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
    }
}

【问题讨论】:

  • 这是 Fizz Buzz 的新名字吗?
  • 不应该标记homeworkinterview吗?

标签: c# unit-testing tdd


【解决方案1】:

您不能从现有代码编写测试驱动代码,因为应该在编写实现之前编写测试

测试代码的最简单方法是向Console.Out 提供TextWriter 模拟并验证生成的输出。

更新:如果您想使用 TDD,那么您应该修改您的代码以使其可测试。在这里,您的Program 类可以做很多事情——它负责表示(输出结果到控制台)和业务逻辑(计算值)。为了测试业务逻辑,您应该将此功能移至单独的类。

让我们开始吧。第一次测试:

[Test]
public void ShoulReturnHoonWhenValueDivisibleOnlyBy3()
{
    var hoonGroup = new HoonGroup();
    string result = hoonGroup.Calculate(3);
    Assert.AreEqual("HOON", result);
}

编译失败,因为你没有HoonGroup 类。创建类,创建方法Calculate。使代码可编译:

public class HoonGroup
{
    public string Calculate(int value)
    {
        return "";
    }
}

现在您的测试失败了,因为您返回的是空字符串。只需硬编码“HOON”即可通过测试。 TDD 没问题。

public class HoonGroup
{
    public string Calculate(int value)
    {
        return "HOON";
    }
}

下一个测试:

[Test]
public void ShoulReturnGroupWhenValueDivisibleOnlyBy5()
{
    var hoonGroup = new HoonGroup();
    string result = hoonGroup.Calculate(5);
    Assert.AreEqual("Group", result);
}

当然,测试失败。更新实施:

public class HoonGroup
{
    public string Calculate(int value)
    {
        return (value == 5) ? "Group" : "HOON";
    }
}

看起来很愚蠢。但它实现了代码的所有要求。另一个测试:

[Test]
public void ShoulReturnNullWhenValueIsNotDivisibleBy3Or5()
{
    var hoonGroup = new HoonGroup();
    string result = hoonGroup.Calculate(5);
    Assert.IsNull(result);
}

没问题 - 添加另一个条件:

public class HoonGroup
{
    public string Calculate(int value)
    {
        if (value == 3)
            return "HOON";

        if (value == 5)
            return "Group";

        return null;
    }
}

测试通过。我们需要更多的测试用例。使用 NUnit 很容易 - 只需使用 TestCase 属性 (MSTest also has similar feature) 装饰第一个测试:

[TestCase(3)]
[TestCase(6)]
[TestCase(99)]
public void ShoulReturnHoonWhenValueDivisibleOnlyBy3(int value)
{
    var hoonGroup = new HoonGroup();
    string result = hoonGroup.Calculate(value);
    Assert.AreEqual("HOON", result);
}

现在更容易创建检查值是否可被 3 整除然后列出所有可能值的代码:

public class HoonGroup
{
    public string Calculate(int value)
    {
        if (value % 3 == 0)
            return "HOON";

        if (value == 5)
            return "Group";

        return null;
    }
}

我想你明白了 TDD 的要点和规律。为可被 5 整除的值创建更多测试用例,并为可被 3 和 5 整除的值编写测试。

【讨论】:

  • 谢谢你的评论,如果我假设我知道我应该在这里写什么并且我想先写测试,你能为上面的逻辑添加简单的例子吗?
【解决方案2】:

如果您有兴趣,这就是使用 TDD 解决 FizzBu​​zz(本质上是相同的问题)的方法。

http://chilliandrew.blogspot.com/2013/12/tdd-so-whats-this-test-first-thing.html

【讨论】:

    【解决方案3】:

    重写您的代码以使其可测试。

    顺便说一句,它看起来不对,所以我会这样写:

    static void Main(string[] args)
    {
        for (int i =1 ; i<=100;i++)
        {
            Console.WriteLine(i.ToString());
    
            var name = GetName(i);
            if (name != null)
            {
                Console.WriteLine(name);
            }
        }
    }
    
    internal static string GetName(int i)
    {
        if (i % 3 == 0)
        {
            if (i % 5 == 0)
            {
                return "HOON Group";
            }
            else
            {            
                return "HOON";
            }
        }
        else if (i % 5 == 0)
        {
            return "Group";
        }
        else
        {
            return null;
        }
    }
    

    现在 GetName 函数可以测试了。

    测试可能如下所示:

    [TestMethod]
    public void TestMethod1()
    {
        Assert.AreEqual("Hoon Group", Program.GetName(15));
        Assert.AreEqual("Hoon", Program.GetName(3));
        Assert.AreEqual("Group", Program.GetName(5));
    
        // test other values here
    }
    

    本示例假设您使用了InternalsVisibleToAttribute。如果没有,请设置 GetName public。欲了解更多信息,请参阅http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-11
      • 2012-06-10
      • 2019-05-27
      • 2016-03-08
      • 2021-10-19
      • 2017-07-30
      相关资源
      最近更新 更多