Reputation: 3945
I am no stranger to testing. I pride my self on have 97% - 100% test coverage. In fact anything below 95% is poor (but thats off topic). I have the following rails controller:
module Api
module Internal
class TwitterController < Api::V1::BaseController
# Returns you 5 tweets with tons of information.
#
# We want 5 specific tweets with the hash of #AisisWriter.
def fetch_aisis_writer_tweets
tweet_array = [];
tweet = twitter_client.search("#AisisWriter").take(5).each do |tweet|
tweet_array.push(tweet)
end
render json: tweet_array
end
private
# Create a twitter client connection.
def twitter_client
client = Twitter::REST::Client.new do |config|
config.consumer_key = ENV['CONSUMER_KEY']
config.consumer_secret = ENV['CONSUMER_SECRET_KEY']
config.access_token = ENV['ACCESS_TOKEN']
config.access_token_secret = ENV['ACCESS_TOKEN_SECRET']
end
end
end
end
end
It's extremely basic to see whats going on. Now I could write the rspec tests to say call this action, I expect json['bla']['text'] to eql bla
.
But there is a couple issues. In order to effectively test this you need twitter API credentials. Thats coupling my code with another service that I am hoping is up and running.
In fact my controller is essentially coupled to twitter.
So - My question is, with out having to mock a web service or a api call (I have seen some blog posts out there on this, and for this piece of code, I feel they are over kill) - How would you test this?
Some people have suggested VCR. Any thoughts on testing API calls like this?
Upvotes: 1
Views: 342
Reputation: 1410
I've found VCR to be a great tool for tests like this - where you don't need a ton of control over what the external service returns, because you don't have a lot of cases to test. You just want to eliminate test flakiness based on whether or not the service is up, and you want to make sure that you get exactly the same fake response every time. I wouldn't say VCR is overkill at all, it's very simple to use - you just wrap your test in a use_cassette
block, run your test, and VCR records the actual response from the service and uses it as the mocked response from then on.
I will say that the "cassettes" that VCR uses to store the mocked responses are fairly complex YAML, and they're not super readable/easy to edit. If you want to be able to easily manipulate the data that's returned so that you can test several code paths, and easily read it so that your mocked data can serve as documentation of the code, I'd look into something more like HttpMock.
One other option, of course, would be to just stub out the private method that calls the external service and have it return your mock data directly. Usually I'd avoid that, so that you can refactor your private method and still be covered, but it might be an option in some cases where the private method is dead simple and unlikely to change, and stubbing it out makes for significantly cleaner tests.
Upvotes: 1