你如何使用rspec测试分叉的代码

时间:2011-05-28 00:33:21

标签: ruby tdd rspec rspec2

我有以下代码

  def start_sunspot_server
    unless @server
      pid = fork do
        STDERR.reopen("/dev/null")
        STDOUT.reopen("/dev/null")
        server.run
      end

      at_exit { Process.kill("TERM", pid) }

      wait_until_solr_starts
    end
  end

我如何有效地使用rspec进行测试?

我想到了什么

Kernel.should_receive(:fork)
STDERR.should_receive(:reopen).with("/dev/null")
STDOUT.should_receive(:reopen).with("/dev/null")
server.should_receive(:run)

2 个答案:

答案 0 :(得分:10)

我对你的示例中的@server实例变量和server方法感到困惑,但这里有一个例子可以帮助你到达目的地:

class Runner
  def run
    fork do
      STDERR.reopen("/dev/null")
    end
  end
end

describe "runner" do
  it "#run reopens STDERR at /dev/null" do
    runner = Runner.new

    runner.should_receive(:fork) do |&block|
      STDERR.should_receive(:reopen).with("/dev/null")
      block.call
    end

    runner.run
  end
end

关键是fork消息被发送到Runner对象本身,即使它的实现在Kernel模块中。

HTH, 大卫

答案 1 :(得分:1)

大卫的解决方案对我们不起作用。也许是因为我们没有使用RSpec 2?

这是有效的。

def run
  fork do
    blah
  end
end

describe '#run' do
  it 'should create a fork which calls #blah' do
    subject.should_receive(:fork).and_yield do |block_context|
      block_context.should_receive(:blah)
    end

    subject.run_job
  end
end

我不确定在调用常量(例如STDERR)时这是如何应用的,但这是我们能够完成fork测试的唯一方法。