stub_api_for method not returning values if "method_missing" defined in model
I have Rspec unit tests that are failing that shouldn't. In one of my models, I receive JSON from an api which may or may not return a set of given fields. The model has a 'method_missing' definition which stubs out values so my json builder view doesn't throw an exception if it calls a value that's not there:
#/models/system_info.rb
class SystemInfo
include Her::Model
parse_root_in_json true, format: :active_model_serializers
include_root_in_json true
root_element :system_info
def method_missing (methid)
Rails.logger.debug "Method not found for #{methid}"
""
end
end
The unit test is structured just like others which pass but don't have the method missing override:
#/spec.system_info_spec.rb
describe SystemInfo do
before (:each) do
@system_info ={
:foo=>"bar",
:baz=>"I forget baz's compliment"
}
end
describe :system_info do
before do
stub_api_for(SystemInfo) do |stub|
stub.get("/system_info/1") { |env| [200, {}, @system_info.to_json ] }
end
end
subject(:system_info) { SystemInfo.find 1 }
its(:foo) { should eql(@system_info[:foo]) }
end
end
This test invariably fails with:
.D, [2014-11-10T15:00:07.673554 #18833] DEBUG -- : Method not found for foo
. . .
Failure/Error: its(:foo) { should eql(@system_info[:foo]) }
expected: "bar"
got: ""
If I remove the method missing definition from the model, the test passes.
This raises some concerns:
- I have explicitly stubbed the api call to return a defined object.
- Functional tests of this model pass and return expected values.
- Why is method missing being called on an attribute that is clearly defined?
- Why is method missing being called at all? I'm accessing attributes of a hash.
- Additionally, I'm not seeing expected logging in my middleware. What is the stub actually calling? What isn't it calling?
- Is there any documentation on stub_api_for? It's not like typical stubs I've seen.
Thanks!
Btw, I think I see it. hash keys can't be called like methods. But that still points to something in translating the return in your code. Used webmocks gem with much greater success.