RSpec 2 'something.should be` - ruby-on-rails

I came across some horrible looking RSpec 2 test:
something.should be
Nope, I didn't accidentally forget to cut+paste the rest of the line,
that's it!
So what's the exact semantic of that? should_not be_nil ?
Please chime in why this is horrible style.
IMHO it's sloppy, not precise, and does not clearly communicate what's required. (it triggers my gag reflex ;)

You're correct - according to the docs object.should.be equals object.should_not be_nil
Documentation, 4th one down in that first list.

From the docs: "We recommend you use the expect syntax unless you have a specific reason you prefer the should syntax. We have no plans to ever completely remove the should syntax but starting
in RSpec 3, a deprecation warning will be issued if you do not explicitly enable it, with the plan to disable it by default in RSpec 4 (and potentially move it into an external gem)."
I believe the equivalent in newer syntax would be:
expect(something).to be
or more commonly:
expect(something).not_to be_false

Related

Why is RuboCop replacing the word "should" with the word "does"?

I'm not sure what is causing it, but the word "should" is being replaced in my code with the word "does". I'm writing a spec in ruby on rails, and I'm trying to follow a BDD approach to my unit tests. One of their recommendations is writing each unit test as a whole sentence, starting with the word, "should", so I wrote the following test:
it 'should not return if there are no existing activities on the project' do
end
The code is being replaced by the following:
it 'does not return if there are no existing activities on the project' do
end
Notice that the word "should" has been replaced. Is this RuboCop? If so, what is the rule I disable to prevent this from happening?
If it's not RuboCop, what could it be?
Well it is actually something Rubocop does for you through RSpec/ExampleWording. Rubocop has an Rspec Style guide, you can check the part about "Should" in Example Docstrings
From the docs:
Do not write 'should' or 'should not' in the beginning of your example
docstrings. The descriptions represent actual functionality, not what
might be happening. Use the third person in the present tense.
So disabling it is actually a bad practice and you should stick to the docs and write your docstrings accordingly.
You can disable RSpec/ExampleWording

What does expect() do in rspec/cucumber?

In Michael Hartl's Rails Tutorial, many examples use an expect() method. Here's one such example in a cucumber step definition:
Then /^she should see her profile page$/ do
expect(page).to have_title(#user.name)
end
This same example can be written as such to the same effect:
Then /^she should see her profile page$/ do
page.should have_title(#user.name)
end
Why use expect()? What value does it add?
There's a documentation on the rspec-expectations gem about this.
Why switch over from should to expect Basically:
should and should_not work by being added to every object. However, RSpec does not own every object and cannot ensure they work consistently on every object. In particular, they can lead to surprising failures when used with BasicObject-subclassed proxy objects.
expect avoids these problems altogether by not needing to be available on all objects.
A more detailed reasons for this is placed in: RSpec's New Expectation Syntax
expect is a bit more universal. You're passing an object or a block to rspec's expect method, rather than attempting to call a should method on objects that are outside of your control. As a result, expect is coming more and more into favor among developers.

Can rspec output the value that made a test fail?

I have statements like:
#obj[:attribute].eql?("TestValue").should be_true
And it would be nice if instead of just telling me that the test failed, it told me that it failed because #obj[:attribute] was nil or was 1234 or whatever it was. Is there any way to do this?
When doing something like
#obj.attribute.should eql(5)
and it throws an error, you'll usually see
expected 5
got 10
Is there a specific reason why you are doing eql??
Sure, rspec does output the difference between expected and actual values. You just need to change your matcher to provide more relevant information to you. Right now your expectation is that the expression #obj[:attribute].eql?("TestValue") will be true and rspec will inform you that it was false instead. If you rewrite your expectation as
#obj[:attribute].should eql("TestValue")
You should see the sort of output you are looking for.

Unresolved ruby reference in RubyMine

Is there any way to avoid the "unresolved ruby reference" warning in RubyMine IDE?
for example, when some code in my view calls a method of the view helper, I get the "unresolved ruby reference" warning even though the code works.
The case described above is just one of many.
Another example is when using RSpec:
it "should require an email" do
no_email_user = User.new(#attr.merge(:email => ""))
no_email_user.should_not be_valid
end
the parameter "be_valid" is not known to the RubyMine IDE.
My question is - is there any way to solve this? should I require additional files? should I do something differently?
Those false positives regarding unresolved ruby methods/constants are really disturbing, and it also affects the results of the "find usages" action in RubyMine.
I'm using RubyMine 3.1
I would really appreciate any help in resolving this issue.
This issue is already submitted to the RubyMine bug tracker, please watch/vote.
I think in this case this is hard to solve. Ruby allows great magic to happen using method_missing and as far as i know, the be_valid is also implemented in this way. Actually there is no be_valid but it calls the valid? method and expects it to be true.
In rspec, this work for any method ending in a ?. So if you have a method ready?, you can write should be_ready.
I am a fulltime Rubymine user, but i do not know how they could solve that nor do i expect it.
To turn off the warning you are getting in RubyMine 3.1, which I think might be your original question, you need to go to File->Preferences. Then, on the left, go to "Inspections". Open up the "Ruby" section and uncheck "Unresolved Ruby Reference." The Preferences is searchable so, if you get others like that, you might try the search. Good luck!

Should I write rails tests with the def or test keyword?

This seems like a simple question but I can't find the answer anywhere. I've noticed that in general, tests in a Ruby on Rails app can be written as:
test "the truth" do
assert true
end
or
def the_truth
assert true
end
It seems newer material writes tests the first way, but I can't seem to find a reason for this. Is one favored over the other? Is one more correct? Thanks.
There has been a shift in recent years from short, abbreviated test names to longer, sentence-like test names. This is partly due to the popularity of RSpec and the concept that tests are specs and should be descriptive.
If you prefer descriptive test names, I highly recommend going with the test method. I find it to be more readable.
test "should not be able to login with invalid password" do
#...
end
def_should_not_be_able_to_login_with_invalid_password
#...
end
Also, because the description is a string it can contain any characters. With def you are limited in which characters you can use.
I believe the first method was implemented starting with Rails 2.2.
As far as I am aware, it simply improves readability of your code (as def can be any function while test is used only in test cases).
Good luck!
As Mike Trpcic suggests you should check out RSpec and Cucumber. I'd like to add that you should also take a look at:
Shoulda (http://github.com/thoughtbot/shoulda/tree/master)
Factory Girl (http://github.com/thoughtbot/factory_girl/tree/master)
Shoulda is a macro framework for writing concise unit tests for your models/controllers, while the second is a replacement for fixtures.
I would suggest doing your testing with either RSpec or Cucumber. I use both to test all my applications. RSpec is used to test the models and controllers, and Cucumber tests the Views (via the included Webrat functionality).

Resources