vendredi 30 juin 2017

How best to test controller variable assignment of has_many associations?

I am trying and failing to test a controller for variable assignment of the belongs_to objects. These are controller tests and there are a number of areas I could really appreciate with some help on, namely

  1. Should I be writing such tests here and in this way.
  2. If so how could i get it working.

Code as below:

Company.rb

class Company < ApplicationRecord
    belongs_to  :user
    has_many        :employees, inverse_of: :company
    has_many        :quotes, inverse_of: :company
end

Quote.rb

class Quote < ApplicationRecord
    belongs_to :company
end

Employee.rb

class Employee < ApplicationRecord
    belongs_to :company
end

Company has a controller with usual CRUDs, Quote has a controller with Show and Index, Employee does not have a controller. Companies#create creates all three objects and redirect_to's to Quotes#show which renders various attrs from all three models.

I have a Factory Girl factory set up for eahc of the models:

Companies.rb

FactoryGirl.define do
  factory :company do
    sequence(:co_name) { |n| "Acme Co #{n}" }
    co_number "06488522"
    postcode "al1 1aa"
    industry :financial_services

    factory :company2 do
    end

    factory :company3 do
    end
  end
end

Quotes.rb

FactoryGirl.define do
  factory :quote do
    lives_overseas true
    payment_frequency :monthly

    factory :quote2 do
    end

    factory :quote3 do
    end
  end
end 

Employees.rb

FactoryGirl.define do
  factory :employee1, class: Employee do
    first_name "MyString"
    last_name "MyString"
    email "MyString"
    initial "MyString"
    gender "MyString"
    date_of_birth "2017-06-20"
    salary 10000

    factory :employee2 do
    end

    factory :employee3 do
    end
  end
end

And I am trying to write controller tests for Quote#show and to test the assignment of the three objects, i.e.; @company, @quote & @employees to the relataive variables. Code so far as below:

quotes_controller_spec.rb

require 'rails_helper'

RSpec.describe QuotesController, type: :controller do
  let(:user) {FactoryGirl.create(:user) }
  let(:company) { FactoryGirl.create(:company, user: user) }
  let(:employee1) { FactoryGirl.create(:employee1, company: company) }
  let(:employee2) { FactoryGirl.create(:employee2, company: company) }
  let(:employee3) { FactoryGirl.create(:employee3, company: company) }
  let(:quote) { FactoryGirl.create(:quote, company: company) }

  describe "GET #show" do
    it "returns http success" do
      get :show, params: { company_id: company.id, id: quote.id }
      expect(response).to have_http_status(:success)
    end

    it "assigns requested quote to @quote" do
        get :show, params: { company_id: company.id, id: quote.id } #, employee_id: employee1.id
        expect(assigns(:quote)).to eq(quote) # passes fine
        expect(assigns(:company)).to eq(company) # passes fine
        expect(assigns(:employees)).to eq() # fails 
    end
  end
end

I get an error as below:

Failures:

  1) QuotesController GET #show assigns requested quote to @quote
     Failure/Error: let(:employee1) { FactoryGirl.create(:employee1, company: company) } #Why can i not use these factories?

     NoMethodError:
       undefined method `initial=' for #<Employee:0x007f86d8b15470>
       Did you mean?  initialize

I feel like there are a few core things I am not getting right here;

a) I need somehow to declare the associations within Factory Girl b) My tests should somehow be testing the presence of a collection and its assignment to the @employees variable in Quotes#show. c) I am unsure about whether I am crossing 'lines of separation' that perhaps ought to be present because I am testing on other model objects (Company, Quote and Employee) created in Companies#create and rendered in Quotes#show.

Any help and or guidance apprecitated. The afternoon reading and googling leaves me still at a loss as to how I can get my testing strategy right here and the syntax correct for it to work properly.

Aucun commentaire:

Enregistrer un commentaire