philihpAboutPGPLightning

How to parameterize an RSpec shared context

I had a RSpec shared_context which was creating a FactoryGirl user mock and then logging in with it, and then running some shared examples for testing permissions on a generic user. I needed to modify it to accept a parameter of using a different user.

It originally looked like this:

RSpec.shared_context "auth" do let(:current_user) { FactoryGirl.create(:user) } before(:each) do allow(User).to receive(:find_by_id) allow(User).to receive(:find_by_id).with(current_user.id) { current_user } end shared_context "logged in" do before(:each) do login_as current_user end end end

In my spec files, it was included by doing this:

describe MyController do include_context 'auth' context "when logged in as a normal user" do include_context 'logged in' ... end end

However I needed MyController to override current_user and use an admin user instead. Rather conveniently, you can override a context by sending it a block.

describe MyController do include_context 'auth' context "when logged in as an admin" do include_context 'logged in' do let(:current_user) { FactoryGirl.create(:admin) } end ... end end

This works because the let inside of the block given is called again, and the new block calls let(:current_user) again and overrides the original block and FactoryGirl.create(:user) is never called.

This is documented here , however they don't really show that it can be used for making your shared_context parameterized. So I'm going to say the word parameterized a lot here, and hope that when I (or you!) google "How do I parameterize an RSpec shared_context?", you find this post.

GitHub · Bluesky · LinkedIn · Instagram · KeybaseRSS

Built from 8f0906ac CC BY 4.0 — with love from San Francisco.