如何对控制台输入类进行单元测试?
在我的一个应用程序中,我有一个负责用户输入的类。默认的输入方式是控制台(键盘),我想为它编写一些单元测试以确保它是正确的。
我正在考虑使用 google-test 框架进行单元测试,这样可以轻松自动化所有测试。但是,我不确定如何自动测试控制台输入。
有没有办法模拟用户在键盘上的输入?或者我是否必须手动输入测试输入?或者也许重定向 stdin
(在代码中或在运行单元测试时通过管道)?
编辑:我计划使用 GNU readline 进行用户输入。目前我看不到任何方法来重定向这个库的输入流 - 也许其他人有这方面的经验?
In one of my applications I have a class which is responsible for user input. The default method of input is the console (keyboard), and I want to write some unit tests for it to make sure it is correct.
I am considering using the google-test framework for my unit testing, which makes it easy to automate all the testing. However, I am not sure how I can automate testing of the console input.
Is there any way to simulate user input on the keyboard? Or do I have to manually enter my test input? Or perhaps redirect stdin
(either in code or by a pipe when running the unit test)?
EDIT: I am planning on using GNU readline for user input. At the moment I can't see any way to redirect the input stream of this library - perhaps someone else has experience with this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您可以使用expect。
You could use expect.
基本上,你的类应该能够使用随机输入流,而不仅仅是标准输入(如果还不能,你必须重构它)。
之后,您将能够简单地将模拟流与自定义数据一起放置并模拟任何用户输入。
Basically, your class should be able to use random input stream, not only stdin (and you have to refactor it, if it's unable yet).
After that you'll be able to simply put a mock stream with your custom data and to simulate any user input.
模拟输入。
Mock the input.
如果您的平台是 .NET,这是一种方法< /a>.
If your platform is .NET, here's one way to do it.
创建一个抽象类,其成员与您要使用的 readline 功能相匹配。针对这个抽象类进行编程,而不是直接针对 readline API 进行编程。使用依赖注入将此类的实例获取到需要它的代码。
然后,您可以创建此类的两个实现:一个仅包装 readline 库,另一个模拟实现可在单元测试中使用。模拟实现将具有额外的成员,可以轻松模拟用户。
Create an abstract class with members that match the readline functionality that you want to use. Program against this abstract class instead of directly against the readline API. Use dependency injection to get an instance of this class to the code that needs it.
Then you can create two implementations of this class: one which simply wraps the readline library, and another mock implementation which you can use in your unit tests. The mock implementation would have extra members that make it easy to simulate a user.
对于 .NET/C#,您可以使用此问题中找到的选项类或变体。因为您已将所有命令映射到委托,所以您可以对委托末尾的每个方法进行单元测试,并轻松找到未知命令:
MyHandler 类将类似于:
For .NET/C# you could use the Options class or variations found in this question. Because you have all commands mapped to delegates, you can then unit test each of the methods at the end of the delegates, and easily find unknown commands:
The MyHandler class would be similar to:
对于控制台,我总是用我自己的实现来包装它。
对单元测试中涉及的所有第 3 方控件使用包装器和接口使得使用隔离框架(如 Rhino Mocks)变得非常容易。它使我能够控制测试,并明确定义代码中的依赖关系。由于我需要控制台的新功能,我可以将它们添加到包装器界面中。我还没有遇到界面膨胀的问题......
这是一个正在进行的测试
For the console, I always just wrap it with my own implementation.
Using a wrapper and interface for all 3rd party controls that are involved in unit tests makes working with an isolation framework (like Rhino Mocks) super easy. It gives me control over testing, and explicitly defines the dependancies in my code. As I need new features of the console I can just add them to the wrappers interface. I have not had issues with interface bloat yet...
Here is a test in action