为什么是$?在RSpec中没有(在Rails应用程序之外)

时间:2016-03-08 18:38:13

标签: ruby rspec

我有一个在测试中使用 public class DapperSetup { public static void InitializeClassMappings() { DapperExtensions.DapperExtensions.SetMappingAssemblies(new[] { typeof(MdCarBrandModelMapper).Assembly }); } } 的Rails应用程序,它运行正常。

我正在尝试制作一个在测试中使用$?.exitstatus的宝石,但我收到了:

$?.exitstatus

以下是我为重现此问题而创建的两个示例文件:

superman.rb

NoMethodError:
   undefined method `exitstatus' for nil:NilClass

my_spec.rb

class Superman
  def self.execute(command)
    `#{command}`
  ensure
    puts $?.exitstatus
  end
end

为什么我可以在我的Rails规范中使用describe Superman do it 'should execute' do expect(Superman).to receive(:execute).and_return(1) expect($?.exitstatus).to be 0 end end ,而不是在普通的ruby中?我需要一些东西吗?

1 个答案:

答案 0 :(得分:3)

$?返回要执行的最后一个子进程的Process::Status。如果没有执行子进程,您将获得nil

在这种情况下,因为您实际上没有调用Superman.execute,所以不会返回子进程状态。此外,即使您将Superman.execute("ls")添加到您的规范中,您也可以将其隐藏在上面,同样仍然适用。

尝试:

describe Superman do
  it 'should execute' do
    # There's really no reason for this expect(..).to receive anyway
    # since it's pretty obvious it's going to get called since we're
    # calling it directly right below.
    expect(Superman).to receive(:execute).and_call_original
    Superman.execute("ls")
    expect($?.exitstatus).to eq(0)
  end
end

收率:

rspec ./superman_spec.rb
0
.

Finished in 0.01054 seconds (files took 0.10346 seconds to load)
1 example, 0 failures