Search code examples
rubyrspectddrspec-railsruby-on-rails-4

Test failure gives incomplete error message when using short syntax


There are 2 syntaxes (afaik) for writing tests with RSpec:

The classic/old way:

  describe "when user_id is not present" do
    before { @micropost.user_id = nil }

    it "should not be valid" do
      @micropost.should_not be_valid
    end
  end

That gives this error when failing:

rspec ./spec/models/micropost_spec.rb:19 # Micropost when user_id is not present should not be valid

And the short syntax:

  describe "when user_id is not present" do
    before { @micropost.user_id = nil }
    it { should_not be_valid }
  end

That gives this error when failing:

rspec ./spec/models/micropost_spec.rb:18 # Micropost when user_id is not present

The last one is missing the "should not be valid" part.

Is there any way to have the complete test failure message, maybe a flag I don't know about?

Note: A more complete error message is still there no matter what:

  1) Micropost when user_id is not present 
     Failure/Error: it { should_not be_valid }
       expected #<Micropost id: nil, content: "Lorem ipsum", user_id: nil, created_at: nil, updated_at: nil> not to be valid
     # ./spec/models/micropost_spec.rb:18:in `block (3 levels) in <top (required)>'

But the recap at the end is incomplete.


Solution

  • The text you see in

    rspec ./spec/models/micropost_spec.rb:19 # Micropost1 when user_id is not present2 should not be valid3

    and

    rspec ./spec/models/micropost_spec.rb:18 # Micropost1 when user_id is not present2 3

    is not the error message, but the test name, which is a concatenation of the current test's description with all its parents' descriptions:

    describe Micropost do # <= 1
      describe "when user_id is not present" do # <= 2
        before { @micropost.user_id = nil }
    
        it "should not be valid" do # <= 3
          @micropost.should_not be_valid
        end
      end
    end
    

    In the short (one-liner) syntax - the test itself does not have a description

    describe Micropost do # <= 1
      describe "when user_id is not present" do # <= 2
        before { @micropost.user_id = nil }
        it { should_not be_valid } # <= 3 - not described!
      end
    end
    

    If you want to force a description on this test you could write it like this:

    it('should not be valid') { should_not be_valid }
    

    But this kind of beats the purpose of the one-liner, which should be self-explanatory, don't you think?