【发布时间】:2020-07-12 00:22:35
【问题描述】:
我正在学习 ruby 并尝试使用 rspec 为以下方法编写单元测试:
def get()
options = {}
OptionParser.new do |opt|
opt.banner = 'Usage: validate-gitlab-ci [options]'
opt.on('-f', '--yaml YAML-PATH', 'Path to .gitlab-ci.yml') { |o| options[:yamlFile] = o }
opt.on('-l', '--base-url GitLab url', 'GitLab API url') { |o| options[:baseUrl] = o + API_PATH }
opt.on('-t', '--timeout[TIMEOUT]', Integer, 'Api timeout in seconds') { |o| options[:timeout] = o || 10 }
opt.on('-v', '--version', 'Program version') { |o| options[:version] = o }
end.parse!
validateUrl!(options[:baseUrl])
validateYamlFile!(options[:yamlFile])
@baseUrl = options[:baseUrl]
@pathToYamlFile = options[:yamlFile]
end
到目前为止,我的单元测试代码是:
RSpec.describe Gitlab::Lint::Client::Args do
describe "#get" do
context "when arguments are valid" do
it "sets baseUrl and pathToYamlFile" do
io = StringIO.new
io.puts "glab-lint --base-url=https://example.com --yaml=valid.ym\n"
io.rewind
$stdin = io
args = Gitlab::Lint::Client::Args.new
args.get()
expect(args.baseUrl).to.eq("https://example.com")
end
end
end
end
我正在尝试为 OptionParser 模拟 STDIN。但是,在执行测试时会显示以下错误:
OptionParser::InvalidOption:
invalid option: --pattern
这是由 end.parse 提出的! get() 方法中的一行
有没有人设法用 stdin 模拟测试 OptionsParser?
更新
我认为正在发生的事情是一些 RSpec 选项,例如--模式??在 STDIN 中被捕获并传递给脚本???或者.... RSpec 正在使用标准输入选项??
阅读此post 似乎表明使用 RSpec 无法实现所需的功能......如果这确实是真的,那么我将在未来迁移到使用替代测试框架来使用 ARGV 的 CLI 项目。有一个建议的解决方法 here 但建议使用环境变量来捕获命令行参数。在这种情况下,需要进一步重构被测软件,纯粹是为了适应 RSpec 测试框架的功能!!
如果我添加一个 puts 语句以在测试脚本中显示 ARGV 的内容,它确认是这种情况,输出如下:
--pattern
spec/**{,/*/**}/*_spec.rb
[--base-url=https://gitlab.com --yaml=valid.ym]
所以.....作为 RSpec 的新手.....我的选择是:
- 更新 get 方法的签名以接受 args 数组:
def get(args)
options = {}
OptionParser.new do |opt|
...
end.parse!(args)
end
这延迟了测试从 ARGV 读取的代码进一步向上调用层次结构的问题
-
修改 ARGV 将前两个参数移出数组,然后在测试完成后将 ARGV 恢复到原始状态。看起来类似的东西已经尝试过here,但没有成功。
-
作为 RSpec 的新手,我不知道的其他一些配置
-
研究替代方案,例如minitest,那可能不修改ARGV数组??
有关选项 3 和 4 的更多信息表示赞赏....
【问题讨论】:
-
哪一行导致错误?
-
@bobrodes 感谢您的回复,感谢 :) get 方法中的
end.parse!行引发了错误 -
对不起,我看到你提到了。这听起来不像您的测试套件的问题。您是否在测试套件之外运行了
#get方法,例如p args.baseurl? -
@bobrodes 谢谢,是的,已经尝试从 rspec 之外的控制台运行它并使用 puts 进行验证
-
抱歉,我只有这些。 :) 根本不知道 RSpec;我使用迷你测试。祝你好运!