2013-05-21 11 views
7

Rubyに関する私の最初の質問。 私はReactorループ内でEventMachineのやりとりをテストしようとしています - それは "機能的な"テストとして分類することができると思います。Ruby EventMachineのテスト

私はサーバーとクライアントという2つのクラスがあります。私は両方の側面をテストしたい - 私は彼らの相互作用について確かめる必要があります。

サーバー:

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 

だから、私は別のアプローチを試み、何を思い付いてきました。

基本的な質問は、どういうわけかshould_reciveを使ってRSpecで自分のコードをテストできますか?

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 

これらのテストのバリエーションをたくさん試してみると、わかりません。私はここに何かが欠けていると確信しています...

ありがとうございます。 EMは、サーバを起動するためにクラスを期待されているので

EchoServer.any_instance.should_receive(:receive_data) 

、上記any_instanceトリックは以下となります。これに

EchoServer.should_receive(:receive_data) 

:私は考えることができる

答えて

4

最も簡単な解決策は、これを変更することですそのクラスのインスタンスがそのメソッドを受け取ることを期待してください。

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)を使用しています。もし可能ならば – Subhas

関連する問題