I am using webmocks with much success to test some API calls in my application. One test however is failing unexpectedly. The method which is failing works fine from the console in development, but in test, the RSpec is throwing an exception.
The method tested:
class MyClass
class << self
. . .
def get_internal_users
response = HTTParty.get(API_URL + '/internal_users.json')
return false unless response.code == 200
response.parsed_response.each { |user| user.symbolize_keys! }
end
end
end
In Rails console: MyClass.get_internal_users
returns a valid array of hashes.
The test:
describe MyClass do
context 'admin overrides' do
before do
@internal_users = {"user_name"=>"test_user"},{"user_name"=>"test_user_2"}
stub_request( :get, API_URL + '/internal_users.json')
.to_return( :status => 200, :body => @internal_users, :headers => {})
end
describe "fetch internal users" do
subject { MyClass.get_internal_users }
it { expect {subject}.to_not raise_error }
end
end
end
Running this test throws the following exception:
Failure/Error: it { expect {subject}.to_not raise_error }
expected no Exception, got #<NoMethodError: undefined method `strip' for [{"user_name"=>"test_user"}, {"user_name"=>"test_user_2"}]:Array>
And there it is. Commenting out it { expect {subject}.to_not raise_error }
causes the test to pass.
I have that same expectation all throughout my code though and it works fine. What is causing the expectation to call strip on an array?
I am using the following libraries:
- rails-4.0.3 rspec-core-2.14.7
- rspec-rails-2.14.1
- rspec-mocks-2.14.6
- rspec-expectations-2.14.5
- httparty-0.13.0
- webmock-1.20.4
UPDATE The issue is a conflict with what state both webmock and httparty expect the body to be in. Following the stack trace. I was able to make the error "go away" changing this method in the httparty gem:
# httparty-0.13.0/lib/httparty/parser.rb
def parse
#body is an array, the return check is throwing the exception:
# return nil if body.nil? || body.strip.empty? || body == "null"
# allow arrays:
unless body.class == Array
return nil if body.nil? || body.strip.empty? || body == "null"
end
if supports_format?
parse_supported_format
else
body
end
end
But I'm reluctant to distribute this gem across all servers this application would be deployed to.
Good thing I didn't know whether this was an httparty issue, webmock issue, rspec issue or some amalgamation of the three. I wound up tracing the request in firebug and inspecting the response headers. I had a notion that the ContentType is instructing httparty how to parse the response. Sure enough:
fixed it. Somebody should have caught that before I did.