如何使用C#对此方法进行单元测试

时间:2011-08-16 01:36:45

标签: c# unit-testing nunit mstest fizzbuzz

我有以下方法,我想对其进行单元测试。可以对方法签名进行更改:

public void PrintNumber()
{
    Enumerable.Range(1, 100).ToList().ForEach(x =>
    {
        if (x % 3 == 0 && x % 5 == 0)
            Console.WriteLine("[35]");
        else if (x % 3 == 0)
            Console.WriteLine("[3]");
        else if (x % 5 == 0)
            Console.WriteLine("[5]");
        else
            Console.WriteLine(x.ToString());
    });
}

我有自己的解决方案,但我想知道我的版本是否最好。

谢谢!

3 个答案:

答案 0 :(得分:8)

为了对此方法进行单元测试,您需要使用代理类包装Console.WriteLine(),并将该类注入您的方法。

public interface IWriter
{
    void Write(string text);
}

public class ConsoleWriter : IWriter
{
    public void Write(string text)
    {
       Console.WriteLine(text);
    }
}

public class StubWriter : IWriter
{
    List<string> values = new List<string>();
    public void Write(string text)
    {
         values.Add(text);
    }

    public List<string> Values { get { return values; } }
}

使用此结构,您可以将方法签名更改为PrintNumber(IWriter writer)并调用编写器。在您的测试方法中,注入StubWriter,在生产中注入ConsoleWriter

答案 1 :(得分:2)

这是一种重写方法的方法

public void PrintNumber(TextWriter writer, 
               Action<TextWriter, int> modHandler) {... }

public void HandleMod(TextWriter writer, int input) {...}

还有一些测试:

void Print_Number_Should_Enumerate_0to100 {...}
void Handle_Mod_Outputs_35_Only_When_Input_35 {...}
void Handle_Mod_Gets_Mod_3_Correct {...}
void Handle_Mode_Gets_Mod_5_Correct {...}
void Handle_Mode_Defaults_To_Outputting_Input {...}

等等。

但是,你不能TDD这个 - 它已经写好了。 TDD涉及首先编写测试。你可以做的是编写测试,然后 refactor 来使测试工作。

答案 2 :(得分:1)

如果您的意思是单元测试,那么您只能验证输出,因为该方法没有输入。我将签名重写为:

public void PrintNumber(TextWriter writer) // use writer.WriteLine instead of console.WriteLine

然后在测试传递中,像StreamWriter一样挂钩到MemoryStream。在从测试方法调用方法之后,应该将输出写入MemoryStream,并且可以验证它是否产生了您期望的输出。

编辑:忽略添加,在生产中,如果你真的想要它写入控制台,请按如下方式调用它:

PrintNumber(Console.Out);
相关问题