-3

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

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

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

谢谢!

4

3 回答 3

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.

于 2011-08-16T01:45:37.267 回答
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涉及首先编写测试。您可以做的是编写测试,然后重构以使测试工作。

于 2011-08-16T01:49:56.893 回答
1

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

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

然后在测试中通过类似于连接到 MemoryStream 的 StreamWriter 的东西。从测试方法调用该方法后,输出应写入 MemoryStream,您可以验证它是否产生了您预期的输出。

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

PrintNumber(Console.Out);
于 2011-08-16T01:42:44.080 回答