Skip to content

Testing Style Guide

nuclearsandwich edited this page Nov 1, 2011 · 1 revision

A log of testing practices, guidelines, and warnings when testing the NOWBOX backend.

let, let!, and subject

Use of let(symbol) &block instead of instance variables is strongly encouraged as the instance variables can leak accidentally into other tests whereas locals cannot. However, let, like subject has a few gotchas.

  • Subjects and collaborators created with let are not created until they are first invoked. If there are expected side-effects of the initialization code, care must be taken to determine that things are run in the correct order. For times when the collaborator must be initialized before the beginning of the test, use let!, which runs before the example starts no matter what.

Example

describe SomeClass
  subject { SomeClass.new "foobar", param: "bazqux" }
  # FAILS
  it "expects something happens after initialization" do
    some_side_effect_of_subject_initialization.should have_happened
  end
  # PASSES
  it "expects something happens after initialization" do
    subject
    some_side_effect_of_subject_initialization.should have_happened
  end
  # BETTER
  it "expects something happens after initialization" do
    expect { subject }.to change { some_side_effect }.from(this).to(that)
  end
end
  • let! has a major disadvantage, since it runs before the example group, ActiveRecord objects persisted to the database within let! do not get removed at the end of the example group. So for ActiveRecord objects please use let and then invoke the local at the start of the example block with a comment stating why.

Example

describe SomeModel
  subject { SomeModel.new "foobar", param: "bazqux" }
  # FAILS WHEN RUN TWICE WITHOUT DROPPING THE DATABASE COMPLETELY
  let!(:existing) { SomeModel.create! name: "foobar", param: "bazquz" }
  it "finds existing records" do
    SomeModel.find_record.should == existing
  end

  # WORKS EVERY TIME BUT IS A LITTLE FUGLY
  let(:existing) { SomeModel.create! name: "foobar", param: "bazquz" }
  it "expects something happens after initialization" do
    existing # intialize existing model
    SomeModel.find_record.should == existing
  end

  # BETTER
  # I don't know yet, still searching.
end

Clone this wiki locally