TDD Beyond Basics : How to Use Fakes to Speed Up Tests


  • To learn how to use fakes to speed up tests.


Let's write a program that ignores comments in the ruby program file and reads only statements that is not a comment.

The Ugly Before Version

This version is stolen from : The Well Grounded Rubyist by David Black. Given a test_file.rb with the following contents :

# This is a comment
This is not a comment
# Another comment

We want to read only the line 'This is not a comment'. Here is the uncommenter_spec.rb:

require_relative 'uncommenter'

describe Uncommenter do
  it "should uncomment a given file" do
    infile = + "/uncommenter/test_file.rb")
    outfile = + "/uncommenter/test_file.rb.out", "w")

    Uncommenter.uncomment(infile, outfile)

    resultfile = + "/uncommenter/test_file.rb.out","r")
    result_string =
    result_string.should == "This is not a comment\n"

Here is the uncommenter.rb

class Uncommenter
  def self.uncomment(infile, outfile)
    infile.each do |line|
      outfile.print line unless line =~ /\A\s*#/

This works but it requires manual deleting of the file test_file.rb.out after test run. You could delete it at the end of the test. That does not change the fact that whenever you access a file system, it's not a unit test anymore. It will run slow. It becomes an integration test and requires setup and cleanup of external resources.

The Sexy After Version

Here is the uncommenter_spec.rb that runs fast:

require_relative 'uncommenter'
require 'stringio'

describe Uncommenter do
  it "should uncomment a given file" do
    input = <<-EOM
    # This is a comment.
      This is not a comment.
    # This is another comment
    infile =
    outfile ="")

    Uncommenter.uncomment(infile, outfile)

    result_string = outfile.string
    result_string.strip.should == "This is not a comment."

This example illustrates using Ruby builtin StringIO as a Fake object. A better name for StringIO is VirtualFile. File accessing is involved. It requires the right read or write mode. It also requires closing and opening the file at the appropriate times.

StringIO is a ruby builtin class that mimics the interface of the file. This version of spec runs faster than the file accessing version. The spec is also smaller. In this case, StringIO is a real object acting as a Fake object. You don't have to manually write and maintain a Fake object for file processing. Just use the StringIO.

Run the spec as follows:

rspec uncommenter/uncommenter_spec.rb --format doc --color


In this article you learned about using Ruby's builtin StringIO as a Fake object for any file accessing operations. Since StringIO mimics the file interface we were able to use it to avoid accessing the file system and we were able to speed up the test.

This concept can be used for writing tests that needs to access external systems. Ideally the external service provider like Twitter, Stripe etc must provide us a Fake version of their API that it can be used in our tests. Our tests will not have to go over the network and it will run very fast. It should be the responsibility of the vendors to maintain the Fake implementation for different versions of their API.

Related Articles

Ace the Technical Interview

  • Easily find the gaps in your knowledge
  • Get customized lessons based on where you are
  • Take consistent action everyday
  • Builtin accountability to keep you on track
  • You will solve bigger problems over time
  • Get the job of your dreams

Take the 30 Day Coding Skills Challenge

Gain confidence to attend the interview

No spam ever. Unsubscribe anytime.