thomasvermaak
thomasvermaak

Reputation: 302

Controller Spec 'Check model Validations'

All of my contracts_controller_spec.rb tests are passing except for one.

It fails with this:

 ContractsController #create redirects to show page when given valid params.
 Failure/Error: expect(assigns[:contract].valid?).to be_true    # factory is missing
 # code_id and maybe others, check model validations
   expected: true value
        got: false

Here is my model:

 class Contract < ActiveRecord::Base
   belongs_to :employee
   belongs_to :client
   belongs_to :primary_care_manager
   belongs_to :code
   has_many :schedules


   attr_accessible :authorization_number, :start_date, :end_date, :client_id,
   :units, :contracted_units, :frequency, :code_id, :primary_care_manager_id,
   :employee_id, :employee_flag

   validates_presence_of :authorization_number, :start_date, :end_date,
   :units, :contracted_units, :frequency, :code_id

   validates_presence_of :client_id, :primary_care_manager_id, unless: Proc.new { |a|
   a.employee_flag }
   validates_presence_of :employee_id, if: Proc.new { |a| a.employee_flag }

and here is the example in my contracts_controller_spec.rb test that fails:

  it "#create redirects to show page when given valid params." do
    contract = attributes_for(:contract)
    post :create, contract: contract
    expect(assigns[:contract]).to be_a Contract
    expect(assigns[:contract].valid?).to be_true    # factory is missing code_id and maybe
            # others, check model validations
    expect(response).to be_redirect
    expect(response).to redirect_to contract_path(id: assigns[:contract].id)
  end

lastly, here is my factory.rb file

   factory :contract do
     association :employee,              factory: :employee
     association :client,                factory: :client
     association :code,                  factory: :code
     association :primary_care_manager,  factory: :primary_care_manager
     sequence(:authorization_number)     { |n| "20007000-#{'%03d' % n}" }
     start_date                          Date.today
     end_date                            Date.today.next_month
     units                               "15 minutes"
     contracted_units                    "20"
     frequency                           "weekly"
     employee_flag                       true
   end

I did check the tail.test.log and saw that while the foreign keys are created they are not available at the time that the this example is run:

  it "#create redirects to show page when given valid params." do

Can someone please help me to understand how to write this test such that I get the timing to work such that the foreign keys show up when I run the above example in my controller test.

Thanks.

Upvotes: 0

Views: 81

Answers (1)

Steve
Steve

Reputation: 15736

The problem is that attributes_for doesn't allocate ids for the associated factories. Factory.build on the other hand does allocate ids for associated factories.

So you can do something like:

contract = Factory.build(:contract).attribues.symbolize_keys

instead of:

contract = attributes_for(:contract)

However there is a downside to using build with associations. In order to generate the id of the associated objects FactoryGirl creates the associated objects, so although build doesn't generally hit the database in this case it will insert a record for each association. If that matters to you then you might want to check out the newer build_stubbed method, see http://robots.thoughtbot.com/post/22670085288/use-factory-girls-build-stubbed-for-a-faster-test .

Upvotes: 1

Related Questions