Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3.1, RSpec: testing model validations

I have started my journey with TDD in Rails and have run into a small issue regarding tests for model validations that I can't seem to find a solution to. Let's say I have a User model,

class User < ActiveRecord::Base   validates :username, :presence => true end 

and a simple test

it "should require a username" do   User.new(:username => "").should_not be_valid end 

This correctly tests the presence validation, but what if I want to be more specific? For example, testing full_messages on the errors object..

it "should require a username" do   user = User.create(:username => "")   user.errors[:username].should ~= /can't be blank/ end 

My concern about the initial attempt (using should_not be_valid) is that RSpec won't produce a descriptive error message. It simply says "expected valid? to return false, got true." However, the second test example has a minor drawback: it uses the create method instead of the new method in order to get at the errors object.

I would like my tests to be more specific about what they're testing, but at the same time not have to touch a database.

Anyone have any input?

like image 788
Feech Avatar asked Sep 24 '11 04:09

Feech


2 Answers

CONGRATULATIONS on you endeavor into TDD with ROR I promise once you get going you will not look back.

The simplest quick and dirty solution will be to generate a new valid model before each of your tests like this:

 before(:each) do     @user = User.new     @user.username = "a valid username"  end 

BUT what I suggest is you set up factories for all your models that will generate a valid model for you automatically and then you can muddle with individual attributes and see if your validation. I like to use FactoryGirl for this:

Basically once you get set up your test would look something like this:

it "should have valid factory" do     FactoryGirl.build(:user).should be_valid end  it "should require a username" do     FactoryGirl.build(:user, :username => "").should_not be_valid end 

Oh ya and here is a good railscast that explains it all better than me:

good luck :)


UPDATE: As of version 3.0 the syntax for factory girl has changed. I have amended my sample code to reflect this.

like image 110
Matthew Avatar answered Sep 23 '22 00:09

Matthew


An easier way to test model validations (and a lot more of active-record) is to use a gem like shoulda or remarkable.

They will allow to the test as follows:

describe User    it { should validate_presence_of :name }  end 
like image 40
nathanvda Avatar answered Sep 23 '22 00:09

nathanvda