[英]Test that I can iterate through dictionary and write keys and values to console
I'm trying to write a console application in C# (which I'm VERY new to) using TDD. 我正在尝试使用TDD用C#(我很陌生)编写一个控制台应用程序。
I'm trying to iterate through a dictionary containing strings as keys and integers as values, and output them to the console as "key: value". 我正在尝试遍历包含字符串作为键和整数作为值的字典,并将它们作为“ key:value”输出到控制台。 I've tried loads of different things and finally found something which might work: 我尝试了很多不同的事情,最后发现了一些可行的方法:
public void ShowContents ()
{
foreach (KeyValuePair<string, int> item in dictionary) {
Console.WriteLine ("{0}: {1}", item.Key, item.Value);
}
}
The problem I'm having is - I don't know how to test this. 我遇到的问题是-我不知道如何测试。 My test looks like this at the moment: 目前我的测试如下:
[Test ()]
public void CanShowContentsOfDictionary ()
{
dictionary.AddWord ("Hello");
Assert.AreEqual ("Hello: 1", dictionary.ShowContents ());
}
And is obviously expecting a return value rather than something being output to console. 并且显然期望返回值,而不是输出到控制台。 I read elsewhere on here that there was no point testing for Console.WriteLine as you just assume it works, and so instead you can use return in this method and then write another method that just writes to console (and therefore doesn't need to be tested). 我在这里的其他地方读到,没有对Console.WriteLine进行点测试,因为您只是假设它可以工作,因此您可以在此方法中使用return,然后编写另一个只写到控制台的方法(因此不需要进行测试)。 The problem with this is that a) I don't know how to write a method that returns all the keys and values; 问题是:a)我不知道如何编写一个返回所有键和值的方法; b) I'm not returning one thing, but a number of different strings. b)我没有返回任何东西,而是返回了许多不同的字符串。
Any advice as to how I go about this? 关于我如何做的任何建议?
You could write a function to return the entire string that would have been output by ShowContents
; 您可以编写一个函数来返回ShowContents
将输出的整个字符串; something like: 就像是:
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();
}
Then your ShowContents
is just: 那么您的ShowContents
就是:
Console.Write(GetContents());
And you can test that GetContents
returns what you expect, without involving Console.WriteLine
. 而且,您可以测试GetContents
返回期望的结果,而无需涉及Console.WriteLine
。
Though you already accepted Blorgbeard answer (which is apparently entirely valid in this case), I'd like to add my two cents to your question. 尽管您已经接受了Blorgbeard的回答(在这种情况下,这显然是完全有效的),但我想在您的问题上加上两美分。
As far as I understand it, you must test the behavior you want to achieve. 据我了解,您必须测试您想要实现的行为。 Effectively the change between your question and the answer makes the test change from "I want to test that this method writes all values to a text reader" to "I want to test that this method returns all values concatenated". 实际上,您的问题和答案之间的更改使测试从“我要测试此方法将所有值都写入文本阅读器”更改为“我要测试此方法返回所有并置的值”。 You're not testing a writing behavior anymore, rather a formatting one. 您不再测试一种书写行为,而是一种格式化行为。
In your case this change is not a problem, but it could be problematic. 对于您而言,此更改不是问题,但可能有问题。 For example imagine that you want to write a big set of data to a stream. 例如,假设您要向流中写入大量数据。 You may want to write it piece by piece in order not to load the entirety of the data in memory. 您可能需要逐段写入,以免将整个数据加载到内存中。 If you test for the concatenated string output your test may pass (if you don't use the full data set, which you usually don't in tests) and fail in production because there is too much data. 如果测试连接的字符串输出,则测试可能会通过(如果您不使用完整的数据集(通常不会在测试中使用)),并且由于数据太多,将导致生产失败。
Anyway, you could test the writing behavior by passing to the method a TextWriter
. 无论如何,您可以通过将TextWriter
传递给方法来测试书写行为。 Then in your test you can pass a custom TextWriter
that lets you check written data. 然后,在您的测试中,您可以通过自定义TextWriter
,以检查写入的数据。 In your production code you would pass Console.Out
to write to the console. 在生产代码中,您将传递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);
You can also use the Console.SetOut
method if you want to prepare the Console
for your tests instead of passing a TextWriter
. 如果要为测试准备Console
而不是传递TextWriter
则也可以使用Console.SetOut
方法。 You can find more information in this article by Mark Seeman. 您可以在Mark Seeman的这篇文章中找到更多信息。 I don't really like to change the output of the Console because I don't like that the method writes to a static text writer. 我真的不喜欢更改控制台的输出,因为我不喜欢该方法写入静态文本编写器。 Nothing tells you that the function writes to the standard output so I prefer to pass the TextWriter as an argument 没有什么告诉您该函数写入标准输出,因此我更喜欢将TextWriter作为参数传递
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.