Reputation: 783
I'm practicing testing (just got into it), and am wondering whether it's better to use shoulda-matchers or Factory Girl - or a combination of both - in testing models. For example, I currently just use the simple shoulda-matchers test, which is nice and straightforward:
RSpec.describe User, :type => :model do
describe User do
it { should validate_presence_of(:username) }
it { should validate_presence_of(:password_decoded) }
it { should validate_length_of(:password).is_at_least(3) }
it { should validate_presence_of(:session_token) }
it { should have_one(:shopping_cart)}
end
end
But, from my understanding, this doesn't actually instantiate a User
object like Factory Girl would. Is the above "sufficient" for testing? Any thoughts appreciated!
Upvotes: 2
Views: 1174
Reputation: 37637
factory_girl and shoulda-matchers do two different things. Most Rails applications need both of those things. It's not either-or. The fact that the same people (Thoughtbot) are behind both gems is a good clue that they're both useful at the same time.
factory_girl allows you to create (only in memory or in the database) objects to use in your tests. Most applications need to create similar objects over and over again in their tests; factory_girl removes the duplication in doing that. It also allows you to customize a predefined object easily (more easily than a Rails fixture, for example). The model spec you showed doesn't need factory_girl, but if you have any code in your models more complicated than basic configuration it will probably be helpful to use factory_girl to create models to test.
shoulda-matchers makes it easier to assert that you got the results you expected in your tests. It provides RSpec matchers for asserting things about models and controllers. Most applications will find shoulda-matchers' ActiveModel matchers useful in ensuring that their models are well validated. (Personally I get more use out of shoulda-matchers' ActiveModel matchers than the ActiveRecord matchers.)
Upvotes: 2
Reputation: 1768
If you are going to have small models and tests you may create your example data using seeds but if you are going to add feature tests as well then I would suggest to use FactoryGirl.
I believe shoulda-matchers is a must for all tests.
Upvotes: 0
Reputation: 2927
For basic associations and validations, I think shoulda matchers are fine. I use Factories to test other methods and more complex validations. Here's a simple example for a method that returns a value based on an instance's attributes. I've also shown how to use sequence to always generate a unique email address which can often trip you up in tests.
class User
def fullname
"#{firstname} #{surname}"
end
end
factories/users.rb
FactoryGirl.define do
sequence(:username) { |n| "user-#{n}" }
factory :user do
email { |_u| "#{FactoryGirl.generate(:username)}@example.com" }
password 'password'
password_confirmation 'password'
firstname 'John'
surname 'Smith'
end
end
user_spec.rb
RSpec.describe User do
describe "#fullname" do
it "returns the first and surnames separated by a space" do
user = FactoryGirl.create(:user)
expect(user.fullname).to eq "John Smith"
end
end
end
Upvotes: 1