craig
craig

Reputation: 26262

Mock the RestClient in a mixin

I have a mixin that uses the RestClient:

module Restable
  def get(url, options={})

      response = RestClient::Request.new(
        :method => :get,
        :url => url,
        :user => options[:user],
        :password => options[:password],
        :headers => { 
          :accept => :json,
          :content_type => :json
        }
      ).execute
    response

  end # /get
end # /Restable

I'd like to able to test the usage of the mixin with valid and invalid credentials.

I'm having difficultly mocking the RestClient. This approach generates errors (warning: previous definition of RestClient was here):

require 'spec_helper'
require File.expand_path('../../../lib/restable', __FILE__)
Describe Restable do

  # create dummy object w/ mixin
  before(:each) do
    @test_obj = Object.new
    @test_obj.extend(Restable)
  end

  url = 'http://domain.tld/'

  context "get" do

    it "an anonymous GET request returns success" do

      RestClient = double
      client = double
      client.stub(:code) { 200 }
      RestClient.stub(:get) { client }

      response = @test_obj.get url
      expect(response.code).to eq(200)
    end

    it "a GET request returns success (200) when valid credentials are supplied to a protected resource" do

      RestClient = double
      client = double
      client.stub(:code) { 200 }
      RestClient.stub(:get) { client }

      url = 'http://domain.tld/private'
      options = {user: 'valid_user', password: 'valid_password'}
      response = @test_obj.get url, options
      expect(response.code).to eq(200)
    end

    it "a GET request returns FORBIDDEN (403) when invalid credentials are supplied to a protected resource" do

      RestClient = double
      client = double
      client.stub(:code) { 403 }
      RestClient.stub(:get) { client }

      url = 'http://domain.tld/private'      
      response = @test_obj.get url, {}
      expect(response.code).to eq(403)
    end

  end # /context
end # /describe

What am I doing wrong?

Upvotes: 0

Views: 1318

Answers (1)

Macro
Macro

Reputation: 306

You can use the Webmock Gem to stub the request and return the body/status code you want.

  • Add webmock gem to your gem file gem webmock
  • Add webmock to your spec helper require 'webmock/rspec'
require 'spec_helper'
require File.expand_path('../../../lib/restable', __FILE__)
Describe Restable do

  # create dummy object w/ mixin
  before(:each) do
    @test_obj = Object.new
    @test_obj.extend(Restable)
  end

  url = 'http://domain.tld/'

  context "get" do

    it "an anonymous GET request returns success" do
      WebMock.stub_request(:get, url).to_return(status: [200, 'OK'], body: { foo: 'bar' }.to_json)
      response = @test_obj.get url
      expect(response.code).to eq(200)
    end

    it "a GET request returns success (200) when valid credentials are supplied to a protected resource" do
      url = 'http://domain.tld/private'
      WebMock.stub_request(:get, url).with(basic_auth: ['valid_user', 'valid_pass']).to_return(status: [200, 'OK'], body: { foo: 'bar' }.to_json)
      options = {user: 'valid_user', password: 'valid_password'}
      response = @test_obj.get url, options
      expect(response.code).to eq(200)
    end

    it "a GET request returns FORBIDDEN (403) when invalid credentials are supplied to a protected resource" do
      url = 'http://domain.tld/private'
      WebMock.stub_request(:get, url).with(basic_auth: ['valid_user', 'invalid_pass']).to_return(status: [403, 'OK'], body: { foo: 'bar' }.to_json)      
      options = {user: 'valid_user', password: 'invalid_password'}
      response = @test_obj.get url, {}
      expect(response.code).to eq(403)
    end

  end # /context
end # /describe

Upvotes: 1

Related Questions