Cleaner Rspec

When simply checking equality or truthiness then
Instead of:
it "should have role set to admin" do
@user.role.should eql('admin')
end

it "should be valid" do
  @user.valid?.should be_true
end

Do:
it { @user.role.should eql('admin') }
it { @user.valid?.should be_true}

Try to stick to one expectation per test block, diverge in exceptional circumstrances, so instead of:
describe "#some_method" do
before(:each) do
@object = Class.new
end

   it "should have attributes set" do
     @object.some_method
     @object.point.should eql(0,0)
     @object.x_axis.should eql(0)
     @object.y_axis.should eql(0)
   end
end

Do:
describe Class do
subject { Class.new }
before(:all) do
subject.some_method
end

   it { subject.point.should eql(0,0) }
   it { subject.x_axis.should eql(0) }
   it { subject.y_axis.should eql(0) }
end

When testing code branching, then instead of repeating and mixing contexts:
describe "#some_method" do
it "should not be valid when some attribute is not set" do
subject.should_not be_valid
end

  it "should have errors set  when some attribute is not set" do
    subject.errors.should_not be_empty
  end

  it "should be valid when some attribute is set" do
    subject.should be_valid
  end

  it "should not have errors set when some attribute is set" do
    subject.errors.should be_empty
  end
end

Separate each branch test and to keep it dry/concise, DO:
describe "#some_method" do
context "when some attribute is not set" do
it { subject.should_not be_valid }
it { subject.errors.should_not be_empty }
end

   context "when some attribute is set" do
     it { subject.should be_valid }
     it { subject.errors.should be_empty }
   end
end

When testing instance methods:

describe "#method_name" do
  ...
end

When testing class methods:

describe ".method_name" do
   ...
end

Do not start testing a method using "context block". Though they can be used interchangeably but use what each is intended for.

Nasir Jamal Over 11 years ago