charlotte-ruby / impressionist

Rails Plugin that tracks impressions and page views
MIT License
1.54k stars 313 forks source link

Please provide documentation on proper testing #142

Open DArrigoni opened 10 years ago

DArrigoni commented 10 years ago

I'm not sure how best to create impressions on my model in a test setup so as to test at an integration level. I'm using FactoryGirl and RSpec. Here was my first rough crack at it and the error I received:

FactoryGirl.define do
  factory :impression do
    ignore do
      impressionable { FactoryGirl.build :impressionable }
      user { FactoryGirl.build :user }
    end

    impressionable_type { 'Impressionable' }
    impressionable_id { impressionable.id }
    user_id { user.id }
    controller_name 'impressionables'
    action_name 'show'
    view_name nil
    request_hash { SecureRandom.hex }
    ip_address "127.0.0.#{rand(0..9)}"
    session_hash { SecureRandom.hex }
    message nil
    referrer nil
  end
end
FactoryGirl.define do
  factory :impressionable
    trait :with_views do
      after_build do |impressionable|
        impressionable.impressions = build_list :impression, 3, impressionable: impressionable
      end
    end
  end
end
class Impressionable
  is_impressionable

  def view_count
    impressionist_count
  end
  . . .
end
it 'should return view count' do
  FactoryGirl.build(:impressionable, :with_views).view_count.should == 3
end
ArgumentError:
       wrong number of arguments (4 for 1..2)
     # ./spec/factories/impressionables.rb:37:in `block (4 levels) in <top (required)>'
     # ./spec/models/impressionable_spec.rb:110:in `block (3 levels) in <top (required)>'
     # ./spec/models/impressionable_spec.rb:111:in `block (3 levels) in <top (required)>'
     # ./spec/models/impressionable_spec.rb:113:in `block (3 levels) in <top (required)>'

Any suggestions on the correct way to set up impressions on models in testing would be appreciated! I will happily format what I learn into a documentation pull request. :)

jpaulo commented 9 years ago

You probably have already found a solution to this by now, but i implemented the same way you did and it worked fine.

@product = FactoryGirl.build(:product, :with_views)

trait :with_views do
  after(:build) do |impressionable|
    impressionable.impressions = build_list :impression, 3, impressionable: impressionable
  end
end

FactoryGirl.define do
  factory :impression do
    impressionable_type { impressionable.class.name }
    impressionable_id { impressionable.id }
    user_id { nil }
    controller_name 'impressionables'
    action_name 'show'
    view_name nil
    request_hash { SecureRandom.hex }
    ip_address Faker::Internet.ip_v4_address
    session_hash { SecureRandom.hex }
    message nil
    referrer nil
  end
end