Recently I was working on the first thoughtbot challenge for prime members. The goal was to create application which can download the XML document from web and then print some statistics.
I've wanted to start with the HTTP download. Of course I was following TDD so I started with tests.
But I had no idea how to test HTTP connections. I did not want to use real XML document and real web servers in my tests. I started to thinking about implementing my really simple web server just for the tests. Oh my god. WRONG WRONG WRONG!
There is much much simpler solution! You can stub HTTP requests in your tests. Although I did not know (and I am still not sure ;) what stubbing is, it was very simple.
As first I've created test:
# spec/shakespeare_analyzer_spec.rb require 'spec_helper' require 'shakespeare_analyzer' describe ShakespeareAnalyzer do describe '#initialize' do it 'reads provided URI and stores its content to @file_content' do stub_request(:get, 'http://www.example.com/test_file.txt').to_return(body: 'This is just a test file!') analyzer = ShakespeareAnalyzer.new('http://www.example.com/test_file.txt') expect(analyzer.file_content).to eq 'This is just a test file!' end end end
And then made it pass:
# lib/shakespeare_analyzer.rb require 'net/http' class ShakespeareAnalyzer attr_accessor :file_content def initialize(uri) @file_content = get_content_from_uri(uri) end private def get_content_from_uri(uri) Net::HTTP.get_response(URI.parse(uri)).body end end
As you can see I've stubbed GET request to
http://www.example.com/test_file.txt to return body
This is just a test file!.
But it is really easy to stub requests with whole files, too.
test_file = File.dirname(__FILE__) + '/test_files/test.xml' stub_request(:get, 'http://www.example.com/test.xml').to_return(body: File.read(test_file))
For more information check webmock page and always follow principles of TDD! ;)