September 18, 2013

Testing HTTP connections in Ruby

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.

I've found two gems for this. webmock and fakeweb. I've decided to use webmock.

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! ;)

Hey there!

My name is Patrik Bóna and I am the only programmer at Memberful. This blog is kind of dead, but I just started my own Ruby on Rails screencast. Follow me on Twitter if you want to be notified about my newest videos.