如何从下面的代码中编写TDD代码?

时间:2014-03-04 09:17:05

标签: c# unit-testing tdd

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

3 个答案:

答案 0 :(得分:12)

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

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

更新:如果您想使用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整除的值写入测试。

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:0)

如果您有兴趣,可以使用TDD解决FizzBu​​zz(基本上是同一个问题)。

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