When you provide a client to remote API, you would provide some means for its users to test their operations.

Surely, they could use webmock to check the ultimate requests that are sent to the server. But doing this, they would inadvertedly specify not their own code, but your client's code too. What do they actually need is a means to stub and check invocations of your client's operations. This way they would back on correctness of your client, and take its interface as an endpoint.

For this reason, we support a special RSpec stubs and expectations. sThey are not loaded by default, so you must require it first, and then include the module:

require "evil/client/rspec"

RSpec.describe CatsClient, "cats.fetch" do
  include Evil::Client::RSpec
  # ...
end

Providing that you defined some client...

class CatsClient < Evil::Client
  option :token
  # ...
  scope :cats do
    option :version
    # ...
    operation :fetch do
      option :id
      # ...
    end
  end
end

... lets write a specification:

require "evil/client/rspec"

RSpec.describe CatsClient, "cats.fetch" do
  let(:client) { CatsClient.new(token: "foo") }
  let(:scope)  { client.cats(version: 1) }

  it "fetches a cat by id" do
    stub_client_operation(CatsClient, "cats.fetch")
      .with(token: "foo", version: 1, id: 8) # full hash of collected options
      .to_return 8 # returned value by operation

    expect(scope.fetch(id: 8)).to eq 8
    expect_client_operation(CatsClient, "cats.fetch")
      .to_have_been_performed
  end
end

Selection

To select stubbed operations you can specify client class:

stub_client_operation(CatsClient)

or its superclass

stub_client_operation(Evil::Client)

or leave it for default Evil::Client:

stub_client_operation()

or add a fully qualified name of the operation (for exact matching):

stub_client_operation(CatsClient, "cats.fetch")

or regexp for partial matching:

stub_client_operation(CatsClient, /fetch/)

or use method with to check options exactly:

stub_client_operation(CatsClient, "cats.fetch").with(token: "foo", version: 1, id: 8)

or partially:

stub_client_operation(CatsClient, "cats.fetch").with(hash_including(id: 8))

or via block:

stub_client_operation(CatsClient, "cats.fetch").with { |opts| opts[:id] == 8 }

Return value

You must define some value returned by a stub:

stub_client_operation(CatsClient, "cats.fetch").to_return(8)

or fall back to original implementation:

stub_client_operation(CatsClient, "cats.fetch").to_call_original

or raise an exception:

stub_client_operation(CatsClient, "cats.fetch").to_raise StandardError, "Wrong id"

Some Hint