1
\$\begingroup\$

I want to replace the array of ips with a method (like known_ips or just ips) but I don't know how.

I'll use this known_ips somewhere else.

describe WelcomeController, type: :controller do
  [
    {
      ip: '73.53.61.23',
      location_name: 'Seattle, Washington, US'
    }, {
      ip: '8.26.157.16',
      location_name: 'San Francisco, California, US'
    }, {
      ip: '174.112.13.21',
      location_name: 'Mississauga, Ontario, CA'
    }
  ].each do |params|
    it 'geolocalizes the visitor based on the ip' do
      allow_any_instance_of(ActionDispatch::Request).to receive(:remote_ip).and_return params[:ip]
      get :index
      expect(controller.current_location.name).to eq params[:location_name]
    end
  end
end
\$\endgroup\$
  • \$\begingroup\$ You should include your other code as well so that we can see what they have in common. \$\endgroup\$ – 200_success Mar 1 '18 at 12:51
  • \$\begingroup\$ Since you are really asking for a solution to a problem and not a code review you should post this on Srack Overflow instead. In the spirit of code review, I would replace the very generic allow_any_instance_of(ActionDispatch::Request).to_receive with expect(controller.request).to_receive \$\endgroup\$ – Marc Rohloff Mar 1 '18 at 17:25
1
\$\begingroup\$

I'll use this known_ips somewhere else.

I'm guessing that "somewhere" will still be in a test file. If so you can put this in support file (which is a common patern in RSpec).

# spec/support/ip_list.rb
IP_LIST = [
  # easily to recognize that IP address is first and the location name the second, but you can use your code that uses Hash here
  ['73.53.61.23',   'Seattle, Washington, US'],
  ['8.26.157.16',   'San Francisco, California, US'],
  ['174.112.13.21', 'Mississauga, Ontario, CA']
]

Then on spec_helper.rb (see this example)

# spec/spec_helper.rb
# after the last require
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }

And in your actual test:

describe WelcomeController, type: :controller do
  it 'geolocalizes the visitor based on the ip' do
    IP_LIST.each do |(ip, location_name)|
      expect(controller.request).to receive(:remote_ip).and_return ip
      get :index
      expect(controller.current_location.name).to eq location_name
    end
  end
end

Note that I nested IP_LIST.each inside the it block, I don't think you need to create one it for each test. This is a personal opinion, I'm not sure what is the best practices here.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.