【问题标题】:Rspec: Checking the content of a system callRspec:检查系统调用的内容
【发布时间】:2021-06-29 17:15:11
【问题描述】:

我的 Rails 项目中有一个 Rake 任务,它通过 system 调用执行 openssl

代码如下所示:

system('bash', '-c', 'openssl cms -verify...')

我需要在 bash 而不是 dash(这是 Ubuntu 上的默认设置)中运行命令才能在命令中使用进程替换。

我需要使用 rspec 创建一个测试,以检查在这种情况下,参数 verify 是否按预期传递。

我尝试了以下方法:

expect(Kernel).to receive(:system) do |args|
  expect(args[2]).to match(/verify/)
end

但是,这只会给我发送到系统的第一个字符串中的第三个字母 - 即来自 bash 的字母 s - 而不是系统调用中发送的第三个参数。

我在这里做错了什么?任何建议将不胜感激。

【问题讨论】:

    标签: ruby-on-rails ruby rspec


    【解决方案1】:

    Args 作为连续参数传递给块,所以如果你想把它们当作一个数组,你需要在do |*args| 中使用一个 splat 运算符:

    expect(Kernel).to receive(:system) do |*args|
      expect(args[2]).to match(/verify/)
    end 
    

    退一步说,理解块参数的工作原理很重要,因为它们不同于方法。例如:

    def my_fn(*args)
      yield(*args)
    end
    
    my_fn(1,2,3) { |args| print args }
    # => 1
    
    my_fn(1,2,3) { |a, b, c| print [a,b,c] }
    # => [1,2,3]
    
    my_fn(1,2,3) { |*args| print args }
    # => [1,2,3]
    

    因此,如果您执行 do |args|(没有 splat),则将 args 变量分配给传递给块的第一个参数 ("bash"),而忽略其他参数。

    【讨论】:

    • 如果最后一个参数很重要,那么expect(Kernel).to receive(:system) do |*,last_cmd| 也比args[2] 更清楚
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多