Ruby EventMachine testing

My first question concerning Ruby. I'm trying to test EventMachine interaction inside the Reactor loop - I guess it could be classified as "functional" testing.

Say I have two classes - a server and a client. And I want to test both sides - I need to be sure about their interaction.

Server:

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

Client:

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

So, I've tried different approaches and came up with nothing.

The fundamental question is - could I somehow test my code with RSpec, using should_recive?

EventMachine parameter should be a class or a module, so I can't send instantiated/mocked code inside. Right?

Something like this?

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

And, if not, how would you do it with EM::SpecHelper? I have this code using it, and can't figure out what I'm doing wrong.

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("x04x05Hello")
          }
        }
      }
    end
  end
end

Tried a lot of variations of these tests and I just can't figure it out. I'm sure I'm missing something here...

Thanks for your help.


The simplest solution that I can think of is to change this:

EchoServer.should_receive(:receive_data)

To this:

EchoServer.any_instance.should_receive(:receive_data)

Since EM is expecting a class to start a server, the above any_instance trick will expect any instance of that class to receive that method.

The EMSpecHelper example (while being official/standard) is quite convoluted, I'd rather stick with the first rspec and use any_instance , just for simplicity's sake.

链接地址: http://www.djcxy.com/p/71608.html

上一篇: 在weblogic中引用用于EAR应用程序的共享Java EE库

下一篇: Ruby EventMachine测试