Rspec: 检查系统调用的内容

Rspec: Checking the content of a system call

我的 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——而不是系统调用中发送的第三个参数。

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

参数作为顺序参数传递给块,因此如果您想将它们视为数组,则需要 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")并忽略其他参数.