7

Rubyに関する私の最初の質問。Reactor ループ内で 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

これらのテストの多くのバリエーションを試してみましたが、私はそれを理解することができません. 私はここで何かが欠けていると確信しています...

ご協力いただきありがとうございます。

4

1 に答える 1

4

私が考えることができる最も簡単な解決策は、これを変更することです:

EchoServer.should_receive(:receive_data)

これに:

EchoServer.any_instance.should_receive(:receive_data)

EM はクラスがサーバーを起動することを想定しているため、上記のany_instanceトリックでは、そのクラスのインスタンスがそのメソッドを受け取ることが想定されます。

EMSpecHelper の例 (公式/標準ですが) は非常に複雑です。簡単にするために、最初の rspec に固執して を使用したいと思いany_instanceます。

于 2013-05-24T04:30:35.370 に答える