简体   繁体   English

测试我可以遍历字典并将键和值写入控制台

[英]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.

相关问题 使用标签助手遍历字典键和输入值 - Iterate Through Dictionary Keys and Input Values using Tag Helpers 是否可以创建一个字典,其中的值可以具有多种数据类型? (另外我如何遍历一个数组作为我的值之一) - Is it possible to create a dictionary in which values can have multiple data types? (Also how do I iterate through an array as one of my values) 我可以使用comboBox中的所有项目遍历字典吗? - Can I iterate through a dictionary using all items in a comboBox? 如何遍历包含字典的字典,该字典包含另一个包含列表的字典 - How can I iterate through a dictionary that contains a dictionary that contains another dictionary which contains a list 遍历注册表项并读取注册表值 - Iterate through registry keys and read registry values 如何遍历“IDictionary”的键和值? - How to iterate through keys and values of an `IDictionary`? 如何通过 ComboBox.Items 遍历字典的键 - How to iterate through the keys of a dictionary via ComboBox.Items 通过字典进行排序并根据键来连接值 - Sort through a dictionary and concatenate values depending on keys 我可以在单元测试中写入控制台吗? 如果是,为什么控制台窗口没有打开? - Can I write into the console in a unit test? If yes, why doesn't the console window open? CodeGo.net&gt;如何遍历字典和比较值? - c# - How to iterate through a dictionary and compare values?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM