Jean-Baptiste
Jean-Baptiste

Reputation: 1562

Passing variable to an rspec test

I am fairly new to rspec test and I have an issue trying to test the location of a user. This a test to mock the behaviour of a country_code to block spam from specific zones.

Here is the code of my service :

class GeocodeUserAuthorizer
  def initialize(user_country_code:)
    @user_country_code = user_country_code
  end

  def authorize!
    user_continent = ISO3166::Country.new(user_country_code).continent

    if user_continent == 'Africa'
      return true
    else
      return false
    end
  end
end

Here is the code of my spec file:

require 'spec_helper'

describe GeocodeUserAuthorizer do
  context 'with a user connecting from an authorized country' do
    it { expect(GeocodeUserAuthorizer.new.authorize!(user_country_code: { "CA" })).to eql(true) }
  end
end

And here is the failure code:

Failures:

1) GeocodeUserAuthorizer with a user connecting from an authorized country Failure/Error: it { expect(GeocodeUserAuthorizer.new.authorize!(user_country_code: { "CA" })).to eql(true) } ArgumentError: missing keyword: user_country_code # ./app/services/geocode_user_authorizer.rb:2:in initialize' # ./spec/services/geocode_user_authorizer_spec.rb:16:innew' # ./spec/services/geocode_user_authorizer_spec.rb:16:in block (3 levels) in <top (required)>' # ./spec/spec_helper.rb:56:inblock (3 levels) in ' # ./spec/spec_helper.rb:56:in `block (2 levels) in '

Can anybody help?

Upvotes: 0

Views: 1651

Answers (2)

Jean-Baptiste
Jean-Baptiste

Reputation: 1562

Ok, so my test was too complicated and lacked separations. Here is a final version that works.

The test:

require 'spec_helper'

describe GeocodeUserAuthorizer do
  let(:geocode_authorizer) { GeocodeUserAuthorizer.new(country_code: country_code) }

  context 'with a user connecting from an unauthorized country' do
    let!(:country_code) { 'AO' }

    it { expect(geocode_authorizer.authorize!).to eql(false) }
  end

  context 'with a user connecting from an authorized country' do
    let!(:country_code) { 'CA' }

    it { expect(geocode_authorizer.authorize!).to eql(true) }
  end
end

The service:

class GeocodeUserAuthorizer
  def initialize(country_code:)
    @country_code = country_code
  end

  def authorize!
    check_country
  end

  protected

    def check_country
      user_continent = ISO3166::Country.new(@country_code).continent

      if user_continent == 'Africa'
        return false
      else
        return true
      end
    end
end

Upvotes: 0

Anthony
Anthony

Reputation: 15957

You didn't call your class correctly, your constructor requires the country code. Try this:

describe GeocodeUserAuthorizer do
  context 'with a user connecting from an authorized country' do
    it { expect(GeocodeUserAuthorizer.new(user_country_code: { "CA" })).authorize!).to eql(true) }
  end
end

Also you'll want to add an attr_reader for user_country_code in your class if you want authorize! to use it without the @ symbol.

Upvotes: 1

Related Questions