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.