Как вы тестируете код, разветвляющийся с помощью rspec - PullRequest
4 голосов
/ 28 мая 2011

У меня есть следующий код

  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 ]

10 голосов
/ 28 мая 2011

Меня смущают переменная экземпляра @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.

НТН, David

1 голос
/ 29 июня 2011

Решение Дэвида не сработало для нас. Может быть, это потому, что мы не используем 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, но это был единственный способ, которым мы смогли выполнить форк-тестирование.

...