RSpec – Bang them all!

Testing Time-Consumption

Writing tests for you code enhances you as a programmer and your code quality, but sometimes it might be a very time-consuming task.
To mitigate time-consumption one should keep his tests as minimal as possible in a way which it can still provide good feedback about the code.
Test code debugging time should be reduced as much as possible, and while there are numerous ways to achieve that I would like to touch a very specific case which I often see.

ActiveRecord save! and create!

What I’m talking about is not using the bang versions of ActiveRecord save/create methods in your tests.
To fill in a gap: bang versions of ActiveRecord objects raises an exception in case the method executed with errors.
Having a user instance which does not pass validations:! raises ActiveRecord::RecordInvalid while returns false.

Code Example

Let’s assume you are making an integration spec. You have a simple User model and want to make sure that when (s)he clicks the “My Account” link current path changes to edit_user_path.

If @user does not pass validation the execution of the spec goes on without interference. RSpec’s failure error might not be very handy:

Failure/Error: current_path.should eq(edit_user_path(@user))
No route matches {:action=>"edit", :controller=>"users"}

You find yourself wasting time on debugging your tests and that’s a bad usage of your expensive time.

What Does This Error Means?

edit_user_path is a url helper of rails which requires an id to be passed to. It may be an integer or an object which responds to the id method.
Since @user did not pass validation, it was not saved to the database and does not have an id, so edit_user_path yells at you.


Using! instead of would have halted execution of the spec, stating specifically what went wrong: ActiveRecord::RecordInvalid error.
The same goes for every other ! and non-! version of methods. The ! version, which raises an exception, is almost always the preferable option when writing tests.
It would spare you time by pointing you directly to the problematic piece of code instead of dragging the problem further on the test, producing an unexpected input to other methods.

So Remember – Don’t leave your tests exposed to such incidents – use bang methods and be safe!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s