Reputation: 2830
I'm new to testing and know there are similar questions, but I can't find a good answer anywhere, so I thought I get this out once and for all.
I have Projects resource wich have many Tasks. I wish to properly test tasks CRUD actions in tasks_controller_spec.rb using Factory Girl. How to do it?
This is the code I have so far, to get you started...
routes.rb
5 resources :projects do
6 resources :tasks
7 end
factories.rb
1 FactoryGirl.define do
2
3 factory :valid_project, :class => Project do
4
5 sequence(:name) do |n|
6 "FactoryProject - #{n}"
7 end
8 sequence(:description) do |n|
9 "Description for the FactoryProject - #{n}"
10 end
11
12 end
13
14 factory :valid_task, :class => Task do
15
16 sequence(:name) do |n|
17 "FactoryTask - #{n}"
18 end
19 sequence(:description) do |n|
20 "Description for the FactoryTask - #{n}"
21 end
22 valid_project
23
24 end
25
26 end
tasks_controller_spec.rb
1 require 'spec_helper'
2
3 describe TasksController do
4
5 before :each do
6 @valid_project = FactoryGirl.create :valid_project
7 end
8
9 describe 'Success' do
10
11 before :each do
12 @valid_attr = FactoryGirl.attributes_for :valid_task
13 end
14
15 it 'Should create new task' do
16 lambda do
17 post :create, :project_id => @valid_project, :task => @valid_attr
18 end.should change(Task, :count).by(1)
19 end
20
21 #it 'Should update the task' do
22 #end
23
24 end
25
26 describe 'Failure' do
27
28 before :each do
29 @invalid_attr = { :name => '', :description => '' }
30 end
31
32 it 'Should not create new task' do
33 lambda do
34 post :create, :project_id => @valid_project, :task => @invalid_attr
35 end.should_not change(Task, :count)
36 end
37
38 end
39
40 end
Upvotes: 1
Views: 1023
Reputation: 10089
FactoryGirl.define do
factory :project do
sequence(:name) { |n| "FactoryProject - #{n}" }
sequence(:description) { |n| "Description for the FactoryProject - #{n}" }
end
factory :invalid_project, :parent => :project do
name nil
description nil
end
factory :task do
sequence(:name) { |n| "FactoryTask - #{n}" }
sequence(:description) { |n| "Description for the FactoryTask - #{n}" }
end
factory :invalid_task, :parent => :task do
name nil
description nil
end
end
As far as linking the tasks the the project, I have not used attributes_for much, so I usually do a build or create and pass the value of the association.
@task = FactoryGirl.build(:task, :project => @project)
Upvotes: 3