EventMachine Rspec连接和send_data测试无法正常工作

时间:2014-06-14 03:13:06

标签: ruby rspec eventmachine

我尝试更新em-irc库以使其与当前版本的Ruby一起使用,并使用一些新功能对其进行更新。我试图让规范适用于我的更改,但它没有像我预期的那样工作。

无论我介绍哪些更改,其中一项无效的测试是send_data上下文。

  subject do
    EventMachine::IRC::Client.new
  end

  ...

  context 'send_data' do
    let(:connection) { mock('Connection') }
    before do
      subject.stub(:conn => connection)
      subject.stub(:connected => true)
    end

    it 'should return false if not connected' do
      subject.stub(:connected => false)
      subject.send_data("NICK jch").should == false
    end

    it 'should send message to irc server' do
      connection.should_receive(:send_data).with("NICK jch\r\n")
      subject.send_data("NICK jch")
    end
  end

在我的代码中引用了这个函数:

  def send_data(message)
    return false unless @connected
    message = message + "\r\n"
    @conn.send_data(message)
    trigger 'send', message
  end

第一次测试;如果未连接subjectsend_data将返回false。但是,第二次测试失败,因为mock('Connection')从未收到send_data次呼叫。这是我收到的失败:

  1) EventMachine::IRC::Client send_data should send message to irc server
     Failure/Error: connection.should_receive(:send_data).with("NICK jch\r\n")
       (Mock "Connection").send_data("NICK jch\r\n")
           expected: 1 time with arguments: ("NICK jch\r\n")
           received: 0 times with arguments: ("NICK jch\r\n")
     # ./spec/lib/em-irc/client_spec.rb:80:in `block (3 levels) in <top (required)>'

我尝试了一些改动,但似乎没有一个改变。即使我在该模拟连接上呼叫connection,我也不明白为什么send_data没有接听send_data来电。它在以前版本的库中工作,唯一的区别是我使用let(:connection){...}而不是@connection = mock('Connection')

1 个答案:

答案 0 :(得分:0)

在rspec中,你需要在事件循环中运行测试。我用这个猴子补丁实现了这个目标:

RSpec::Core::Example.class_eval do
  alias ignorant_run run

  def run(example_group_instance, reporter)
    result = false

    Fiber.new do
      EM.run do
        df = EM::DefaultDeferrable.new
        df.callback do |test_result|
          result = test_result
          # stop if we are still running.
          # We won't be running if something inside the test
          # stops the run loop.
          EM.stop if EM.reactor_running?
        end
        test_result = ignorant_run example_group_instance, reporter
        df.set_deferred_status :succeeded, test_result
      end
    end.resume

    result
  end
end