我有以下方法,我想对其进行单元测试。可以对方法签名进行更改:
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());
});
}
我有自己的解决方案,但我想知道我的版本是否最好。
谢谢!
答案 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);