سؤال

I have a protected method in controller and need to write the test case for it. The method is

def source
  @source.present? ? @source.class : Association.reflect_on_association(source.to_sym).klass
end

where @source will be an object and source will be a string.

I have no idea how to write the test case for this method.

edit

Here is what I am trying

subject { @controller }
describe '#source' do

  let(:source_object) { create :program_type}

  describe "Object is not present" do

    it 'should reflect on association and return the reflection class' do
      subject.stubs(:source_identifier).returns("program_type")
      subject.send(:source).must_equal ProgramType
    end
  end

  describe "Object is present" do
    it 'should return the class of the object' do
      subject.send(:source).must_equal source_object.class
    end
  end

end

Thanks in advance.

هل كانت مفيدة؟

المحلول 3

I fixed it. The problem was return string in the first test and object in the second. Here is what i did to fix.

describe '#source' do
  describe "Object is not present" do
    it 'should reflect on association and return the reflection class' do
      subject.stubs(:source_identifier).returns("program_types")
      subject.send(:source).must_equal ProgramType
    end
  end
  describe "Object is present" do
    it 'should return the class of the object' do
      subject.instance_variable_set(:@source, create(:program_type))
      subject.send(:source).must_equal ProgramType
    end
  end
 end

نصائح أخرى

For testing controllers I have following tutorials as references

1 - http://everydayrails.com/2012/04/07/testing-series-rspec-controllers.html

2 - https://gist.github.com/delphaber/d898152eee04cea4964f (more of a cheet sheet)

However it seems to me your method should move to a model or lib. (I'm just guessing by looking at your code) and another thing is if you cannot isolate a method for testing, probably you might have to re-think about the design :)

In general I would suggest not writing tests for protected controller methods, they should be exercised by whichever publicly facing method calls them.

In your case so long as you test whatever calls source, you will be testing source.

If you really need to though you can do;

@controller = MyController.new
@controller.send(:source) #this will call source
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top