2013-05-21 49 views
7

我的第一个关于Ruby的问题。 我试图测试反应堆循环内的EventMachine交互 - 我想它可以归类为“功能”测试。Ruby EventMachine测试

说我有两个类 - 一个服务器和一个客户端。我想测试双方 - 我需要确定他们的互动。

服务器:

require 'singleton' 

class EchoServer < EM::Connection 
    include EM::Protocols::LineProtocol 

    def post_init 
    puts "-- someone connected to the echo server!" 
    end 

    def receive_data data 
    send_data ">>>you sent: #{data}" 
    close_connection if data =~ /quit/i 
    end 

    def unbind 
    puts "-- someone disconnected from the echo server!" 
    end 
end 

客户:

class EchoClient < EM::Connection 
    include EM::Protocols::LineProtocol 

    def post_init 
    send_data "Hello" 
    end 

    def receive_data(data) 
    @message = data 
    p data 
    end 

    def unbind 
    puts "-- someone disconnected from the echo server!" 
    end 
end 

所以,我尝试了不同的方法,用一无所获。

根本的问题是 - 我可以以某种方式测试我的代码与RSpec,使用should_recive?

EventMachine参数应该是一个类或一个模块,所以我不能在里面发送实例化/模拟代码。对?

这样的事情?

describe 'simple rspec test' do 
    it 'should pass the test' do 
    EventMachine.run { 
     EventMachine::start_server "127.0.0.1", 8081, EchoServer 
     puts 'running echo server on 8081' 

     EchoServer.should_receive(:receive_data) 

     EventMachine.connect '127.0.0.1', 8081, EchoClient 

     EventMachine.add_timer 1 do 
     puts 'Second passed. Stop loop.' 
     EventMachine.stop_event_loop 
     end 
    } 
    end 
end 

而且,如果不是,你会如何处理EM :: SpecHelper?我有这个代码使用它,并无法弄清楚我做错了什么。

describe 'when server is run and client sends data' do 
    include EM::SpecHelper 

    default_timeout 2 

    def start_server 
    EM.start_server('0.0.0.0', 12345) { |ws| 
     yield ws if block_given? 
    } 
    end 

    def start_client 
    client = EM.connect('0.0.0.0', 12345, FakeWebSocketClient) 
    yield client if block_given? 
    return client 
    end 

    describe "examples from the spec" do 
    it "should accept a single-frame text message" do 
     em { 
     start_server 

     start_client { |client| 
      client.onopen { 
      client.send_data("\x04\x05Hello") 
      } 
     } 
     } 
    end 
    end 
end 

尝试了很多这些测试的变化,我只是无法弄清楚。我敢肯定我在这里失去了一些东西...

感谢您的帮助。

回答

4

,我能想到的最简单的方法是可以改变:

EchoServer.should_receive(:receive_data) 

要这样:

EchoServer.any_instance.should_receive(:receive_data) 

由于EM期待一个类来启动服务器,上面any_instance诀窍期望该类的任何实例接收该方法。

EMSpecHelper例子(虽然是官方的/标准的)是相当复杂的,我宁愿坚持第一个rspec并使用any_instance,只是为了简单起见。

+1

它的工作原理。有一件事要记住,should_recive存根方法,所以它的行为就像方法中没有任何东西。谢谢。 – pfh

+0

http://axonflux.com/rspecs-shouldreceive-doesnt-ac – pfh

+1

是的,RSpec也支持[再次调用原始方法](https://www.relishapp.com/rspec/rspec-mocks/v/2- 12/docs/message-expectations/calling-the-original-method)自v2.12开始。 – Subhas