2
\$\begingroup\$

Consider following example (controller):

MyController < ApplicationController
    def index
      @objects = Object.fancy_way_of_retrieval
      @properties = Property.fancy_way_of_retrieval_two

      @something_else = @objects.do_something
    end

    def another_method
      @something_other = SomethingOther.get_values
      @objects = Object.fancy_way_of_retrieval
      @properties = Property.fancy_way_of_retrieval_two
    end
  end

First thing I did is to move the duplicate code in the before_filter

MyController < ApplicationController 
before_filter :set_variables

  def index
    @something_else = @objects.do_something
  end

  def another_method
    @something_other = SomethingOther.get_values
  end

private
  def set_variables
    @objects = Object.fancy_way_of_retrieval
    @properties = Property.fancy_way_of_retrieval_two
  end
end

Which looks better, right? Now on to the test :

describe 'before filters' do
  let(:objects) { [FactoryGirl.build_stubbed(:object)] }
  let(:properties) { [FactoryGirl.build_stubbed(:property)] }

  before do
    allow(Object).to receive(:fancy_way_of_retrieval).and_return { objects } 
    allow(Property).to receive(:fancy_way_of_retrieval_two).and_return { properties } 
  end

  it 'assigns objects' do
    get :index
    expect(assigns(:objects)).to eq(objects)
  end

  it 'assigns properties' do
    get :index
    expect(assigns(:properties)).to eq(properties)
  end
end

Now onto the controller action method test :

describe '#index' do
  let(:objects) { [FactoryGirl.build_stubbed(:object)] }
  let(:properties) { [FactoryGirl.build_stubbed(:property)] }

  before do
    allow(Object).to receive(:fancy_way_of_retrieval).and_return { objects } 
    allow(Property).to receive(:fancy_way_of_retrieval_two).and_return { properties } 
  end

  it 'asssigns something else' do
  ....
  end
end

See I had to write the let and before blocks for objects and properties stubs for both before filter method and the controller action method, in order for test to pass. Because the @something_else uses the @objects instance variable.

How do I do this without repeating this bit of code?

\$\endgroup\$

Your Answer

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

Browse other questions tagged or ask your own question.