我试图使用TDD在C#(我非常新)中编写控制台应用程序。
我试图遍历包含字符串作为键和整数作为值的字典,并将它们作为"键:值"输出到控制台。我尝试过很多不同的东西,最后找到了可能有用的东西:
public void ShowContents ()
{
foreach (KeyValuePair<string, int> item in dictionary) {
Console.WriteLine ("{0}: {1}", item.Key, item.Value);
}
}
我遇到的问题是 - 我不知道如何测试这个问题。我的测试目前看起来像这样:
[Test ()]
public void CanShowContentsOfDictionary ()
{
dictionary.AddWord ("Hello");
Assert.AreEqual ("Hello: 1", dictionary.ShowContents ());
}
显然期望返回值而不是输出到控制台的东西。我在这里读到其他地方没有针对Console.WriteLine的测试,因为你只是假设它有效,所以你可以在这个方法中使用return然后编写另一个只写入控制台的方法(因此不会需要测试)。这个问题是:a)我不知道如何编写一个返回所有键和值的方法; b)我没有返回一件事,而是返回了许多不同的字符串。
关于我如何做到这一点的任何建议?
答案 0 :(得分:3)
您可以编写一个函数来返回ShowContents
输出的整个字符串;类似的东西:
public string GetContents()
{
var sb = new StringBuilder();
foreach (KeyValuePair<string, int> item in dictionary) {
sb.AppendLine(string.Format("{0}: {1}", item.Key, item.Value));
}
return sb.ToString();
}
然后你的ShowContents
只是:
Console.Write(GetContents());
您可以测试GetContents
返回您的预期,而不涉及Console.WriteLine
。
答案 1 :(得分:1)
虽然你已经接受了Blorgbeard的回答(在这种情况下显然完全有效),但我想在你的问题中加上我的两分钱。
据我了解,您必须测试您想要实现的行为。实际上,您的问题和答案之间的变化会使测试发生变化,我希望测试此方法是否将所有值都写入文本阅读器&#34; to&#34;我想测试这个方法返回连接的所有值&#34;。您不再测试写作行为,而是格式化。
在您的情况下,此更改不是问题,但可能会出现问题。例如,假设您要将大量数据写入流。您可能希望逐个编写它,以便不将整个数据加载到内存中。如果您测试连接的字符串输出,您的测试可能会通过(如果您不使用通常不在测试中的完整数据集)并且因为数据太多而无法生产。
无论如何,你可以通过传递方法a TextWriter
来测试写作行为。然后,在测试中,您可以传递一个自定义TextWriter
,以便您检查书面数据。在生产代码中,您可以通过Console.Out
写入控制台。
public void ShowContents (TextWriter writer)
{
foreach (KeyValuePair<string, int> item in dictionary) {
writer.WriteLine ("{0}: {1}", item.Key, item.Value);
}
}
// calling in production code
ShowContents(Console.Out);
如果您要为测试准备Console.SetOut
而不是传递Console
,也可以使用TextWriter
方法。您可以通过Mark Seeman在this article中找到更多信息。我不想更改控制台的输出,因为我不喜欢该方法写入静态文本编写器。没有什么告诉你函数写入标准输出,所以我更喜欢将TextWriter作为参数传递