ruby - 如何使用 rspec 为 HighLine gem 测试 IO?
问题描述
我有一堂课:
class Asker
def initialize
@cli = HighLine.new
end
def exit_or_continue
answer = @cli.ask "Type 'quit' to exit at any time, Press 'Enter' to continue"
exit(0) if answer == 'quit'
end
end
我该如何测试该exit_or_continue
方法?
解决方案
据我了解,您想exit_or_continue
根据用户输入测试方法。在这种方法中,有两个主要的重要事项。其中一个是执行的用户输入,@cli.ask
另一个是exit
如果用户输入是 则退出程序的方法quit
。
为了测试这些流程,我们需要同时存根Kernel.exit
和HighLine#ask
方法。首先,我们覆盖类Kernel.exit
实例中的方法Asker
。该Kernel
模块包含在类中,并且每个类都隐式地在 ruby 中Object
扩展类。Object
所以我们的Asker
类有Kernel
默认的方法。
为什么我们exit
在类的实例中存根方法Asker
是因为如果我们在全局(在内核中)存根它会导致意想不到的问题。更重要的是,除非我们 stub 这个方法 rspec 退出并且其余的测试都不会运行。
其次,我们需要存根HighLine#ask
方法等待来自客户端的输入。HighLine#ask
是方法,这Kernel.gets
在引擎盖下使用。通过存根这个方法,基本上我们说'请返回这个值,不要等待用户输入。'。换句话说,@cli.stub(ask: 'quit')
这将返回quit
或您想要的任何内容,而无需提示。
所以我认为以下测试将满足您的需求。如果您遇到任何问题,请随时发表评论。
RSpec.describe Asker do
describe '#exit_or_continue' do
before do
@asker = Asker.new
@cli = @asker.instance_variable_get('@cli')
@asker.stub(exit: true) # We override Kernel.exit method inside asker instance
end
context 'when user input is quit' do
it 'returns true' do
@cli.stub(ask: 'quit') # We stub HighLine#ask method to return quit on behalf of the user.
expect(@sker.exit_or_continue).to be(true)
end
end
context 'when user is input is NOT quit' do
it 'returns nil' do
@cli.stub(ask: 'invalid response') # We stub HighLine#ask method to return invalid response on behalf of the user.
expect(@sker.exit_or_continue).to be_nil
end
end
end
end
推荐阅读
- mysql - 为什么我的公用表表达式查询不适用于 Mysql?
- python - 从 Python 调用多个 .exe
- python - 如何在 pythonanywhere 上运行 django-made venv?
- regex - 正则表达式,崇高语法文件,匹配除特定组之外的特定字符之后的所有内容
- javascript - 使用带有猫鼬函数的 Promise
- c# - 如何从 program.cs 中的 appsettings 中读取 UrlPrefixes - asp.net core 3.1
- c# - 无法使用文件路径将通用 base64 图像发送到 API
- verilog - 为什么这个输出会延迟一下?
- c++ - C++ typename 嵌套类模板
- javascript - 具有类型和默认值的 Javascript 方法