RSpec - Object References Itself
Just came across this problem when using RSpec in one the Rails project that I am working on: object references itself.
Object references itself
The project is basically a REST web service which return a project information in JSON format.
In the template file, there is
r.element :project, @project do |project|
r.element :type
r.element :manager
end
Which is basically the details of the project including the manager of the project. The manager, is an object, not just a string. Rails is smart enough to map the manager structure into JSON …
As you would have expected the spec
files,
let(:manager) { mock(Manager, first_name: "John", last_name: "Doe") }
let(:project) do
project = Project.from_attributes(type: 'business')
project.stub!(:manager).and_return(manager);
end
context 'project' do
subject { custom_render(project) }
it { subject.should include('manager') }
end
When the test is run, it failed with Object references itself
The cause
It took a while to figure out what was the problem. Turned out that’s because the rspec mock potentially have several methods or attributes that reference itself.
mock(Manager, first_name: "John", last_name: "Doe")
When the above line is executed, it practically creates all the bells and whistle that the mock
object has and put all of that onto :manager
r.element :manager
The solution
So the solution was to make sure that we only want to put certain attributes into the view
files. Thus the code was updated to
r.element :project, @project do |project|
r.element :type
r.element :manager do |manager|
r.element :type, manager.type
r.element :name, manager.name
end
end
and things were working fine again. Both the test and the actual REST web service.
Gotcha
If you notice, the above code potentially has one flaw, what if a project doesn’t have a manager. The attempt to get the manager’s name would crash the web service. Thus it would be good to validate that condition before hand.