protobuf-rspec gem

RSpec Helpers designed to give you mock abstraction of client or service layer. Require as protobuf/rspec/helpers and include into your running RSpec configuration.

Note: Tested to work with the protobuf gem (>= 1.0).

Mocking Client Requests (Outside-In test of the service methods)

Use this method to call a local service in your application to test responses and behavior based on the given request. This should be used to outside-in test a local RPC Service without testing the underlying socket implementation or needing actual client code to invoke the method(s) under test.

Given the service implementation below:

module Proto
  class UserService < Protobuf::Rpc::Service
    def create
      user = User.create_from_proto(request)
      self.response = ProtoRepresenter.new(user).to_proto
    end
  end
end

This could be one way to test the implementation while ignoring the RPC backend:

describe Proto::UserService do
  describe '#create' do
    it 'creates a new user' do
      create_request = Proto::UserCreate.new(...)
      client = call_local_service(Proto::UserService, :create, create_request)
      client.response.should eq(some_response_object)
    end
  end
end

Mocking Service Responses

Create a mock service that responds in the way you are expecting to aid in testing client -> service calls. In order to test your success callback you should provide a :response object. Similarly, to test your failure callback you should provide an :error object. If you would like to test the object that is given as a request you should provide a :request object.

Testing the client on_success callback

  # Method under test
  def create_user(request)
    status = 'unknown'
    Proto::UserService.client.create(request) do |c|
      c.on_success do |response|
        status = response.status
      end
    end
    status
  end
  ...

  # spec
  it 'verifies the on_success method behaves correctly' do
    mock_remote_service(Proto::UserService, :client, response: mock('response_mock', status: 'success'))
    create_user(request).should eq('success')
  end

Testing the client on_failure callback

# Method under test
def create_user(request)
  status = nil
  Proto::UserService.client.create(request) do |c|
    c.on_failure do |error|
      status = 'error'
      ErrorReporter.report(error.message)
    end
  end
  status
end
...

# spec
it 'verifies the on_success method behaves correctly' do
  mock_remote_service(Proto::UserService, :client, error: mock('error_mock', message: 'this is an error message'))
  ErrorReporter.should_receive(:report).with('this is an error message')
  create_user(request).should eq('error')
end

Testing the given client request object

# Method under test
def create_user
  request = ... # some operation to build a request on state
  Proto::UserService.client.create(request) do |c|
    ...
  end
end
...

# spec
it 'verifies the request is built correctly' do
  expected_request = ... # some expectation
  mock_remote_service(Proto::UserService, :client, request: expected_request)
  create_user(request)
end

Feedback

Feedback and comments are welcome:

Web: rand9.com Twitter: @localshred Github: github