Skip to content

Testing WebsocketRails Controllers

Steve Gattuso edited this page Aug 10, 2015 · 4 revisions

The websocket-rails gem ships with a few custom matchers and helper methodes to help testing your WebsocketRails Controller and your Event Router.

This means it is possible to simulate the receiving of a message from a client in order to test the behaviour of a WebsocketRails Controller.

Helper Functions

  • create_event(event_name, event_data) is used to create an event with the given name and data as if it was received from a client
  • method dispatch, invoked on the object returned by create_event, dispatches the event through the Event Mapper and invokes the corresponding method(s) in the target controller(s). Thus it is possible to verify the behaviour of the application upon reception of a client message.

Routing Matchers

The routing matchers, as the name suggest, verify that the events and controllers defined in the events.rb file are behaving as expected.

  • be_routed_to verifies that a given event is non-exclusively routed to the desired controller
  • be_routed_only_toon the other hand verifies that a given event is routed to and only to the desired controller.

The routing matchers accept as parameter the expected target, either expressed as a Hash ({ :to => ProductController, :with_method => :update_product}} or as a String ('product#update_product').

Example

# app/controllers/websocket_controllers.rb

class ProductController < WebsocketRails::BaseController

  def update_product
    # code here
  end

  def delete_product
    # code here
  end

end

class WarehouseController < WebsocketRails::BaseController

  def remove_product
    # code here
  end

end

and your events.rb is

# app/config/initializers/events.rb

WebsocketRails::EventMap.describe do
  namespace :product do
    subscribe :update, :to => ProductController, :with_method => :update_product
    subscribe :delete, :to => ProductController, :with_method => :delete_product
    subscribe :delete, :to => WarehouseController, :with_method => :remove_product
  end
end

then you could write the following spec file

# spec/config/initializers/events_spec.rb

describe 'Event Mapping for MyApp' do

  describe 'product.update' do

    it 'should be routed correctly' do
      create_event('product.update', nil).should be_routed_only_to 'product#update_product'
    end

  end

  describe 'product.delete' do
    
    it 'should be routed correctly' do
      # feel free to split the should statements into separate examples, not done here for brevity's sake
      create_event('product.delete', nil).should be_routed_to 'product#delete_product'
      create_event('product.delete', nil).should be_routed_to 'warehouse#delete_product'
    end

  end

end

Trigger Matchers

Trigger matchers verify that a WebsocketRail Controller trigger or does not trigger message during the execution of the code bound to an event. All the trigger matchers can verify also the data associated with the trigger (see paragraph Data Verification below)

  • trigger_message verifies that a message was triggered as response to the event, without checking whether it was failure or success
  • trigger_failure_message verifies that a failure message was triggered
  • trigger_success_message verifies that a success message was triggered

Data Verification

The trigger matchers take an optional data parameter that is used to verify the data associated with the trigger in the following manner.

  • If no data parameter is specified, no data check is performed, i.e. the data associated with the trigger can have any value, including no data at all
  • If the data parameter is set to :any, the matcher will check that there is any data associated with the trigger, i.e. it will succeed when there is data attached to the trigger, but fail if no data is attached to the trigger
  • If the data parameter is set to :nil, the matcher will check that there is no data associated with the trigger, i.e. it will fail if there is data attached to the trigger
  • If the data parameter is set to anything else, the matcher will perform an eql?comparison between the actual data and the data parameter

Example

Expanding the example used for the route matchers we could define a spec for ProductController like

# spec/controllers/websocket_controllers_spec.rb

describe 'Websocket Controllers' do

  describe 'ProductController' do # as it is not a standard Rails Controller we have to use quotes

    it 'should trigger a success message on product.update' do
      create_event('product.update', nil).dispatch.should trigger_success_message
    end

    it 'should trigger a failure message on product.delete with wrong id' do
      create_event('product.delete',{product_id: 'wrong_id'}).dispatch.should trigger_failure_message {reason: 'Wrong Id'}
    end

    it 'should produce a non empty failure message on error' do
      create_event('product.delete',"data that makes it fail").dispatch.should trigger_failure_message :any
    end

  end

end

Usage

Just add

require 'websocket_rails/spec_helpers'

somewhere in your spec/spec_helper.rb file and write your tests.