需要帮助理解为什么方法的单元测试不起作用

时间:2013-04-11 15:39:39

标签: ruby-on-rails unit-testing

我正努力在我的单元测试中覆盖我的所有模型的方法,关联和验证,到目前为止,它很棒。我订阅了TreeHouse并且虔诚地观看了Ruby Foundations - Testing

我在测试我的Provider.rb模型的方法时偶然发现了这个错误:

class Provider < ActiveRecord::Base

  attr_accessible :description, :name
  validates :name, :presence => true
  validates :description, :presence => true
  validates :name, :length => { :minimum => 6, :maximum => 100 }
  validates :description, :length => { :minimum => 6, :maximum => 100 }
  has_many :courses
  resourcify

  def unique_locations
    Location.joins(sessions: :course).where(courses: { provider_id: self.id }).uniq.pluck('locations.name')
  end

end

我对unique_locations方法的单元测试如下:

  test 'should return a list of unique locations' do
    provider = FactoryGirl.build(:provider)
    assert_equal provider.unique_locations, ["location_1", "location_2"]
  end

运行测试后出现以下错误:

<[]> expected but was
<["location_1", "location_2"]>.

我的工厂很简单:

FactoryGirl.define do
  factory :course do
    name 'Snowboard 101'
    description 'Snowboard course'
    association :provider, factory: :provider
  end
end

FactoryGirl.define do
  factory :provider do
    name 'The School of Hard Knocks'
    description 'School description'
  end
end

FactoryGirl.define do
  factory :session_snowboard, class: Session do
    name 'Winter Session'
    description 'Snowboarding 101'
    price 200
    class_size 4
    association :course, factory: :course
    association :location, factory: :location_1
  end

  factory :session_ski, class: Session do
    name 'skiing 101'
    description 'Start in november'
    price 100
    class_size 4
    association :course, factory: :course
    association :location, factory: :location_2
  end

end

FactoryGirl.define do
  factory :location_1 do
    name 'location_1'
  end

  factory :location_2 do
    name 'location_2'
  end

end

我的unique_locations方法在我的不同环境中运行良好。我无法弄清楚为什么它没有返回测试中唯一位置的列表。

有什么想法吗?

谢谢, 弗朗西斯

2 个答案:

答案 0 :(得分:0)

您正在调用FactoryGirl.build(:provider),它只会构建并且不会保存到数据库中,因此unique_locations显然不会拥有该ID。使用create,它应该没问题。

答案 1 :(得分:0)

所以在经过Factory_Girl的讨论后,我找到了解决方案:

这是我的工厂:

FactoryGirl.define do
  factory :provider do
    name 'McGill University'
    description 'McGill is one of the best universities in the world.'
    after(:create) {|provider| create_list(:course, 2, provider: provider) }
  end
end

FactoryGirl.define do
  factory :course do
    name 'Snowboard 101'
    description 'Snowboard course'
    provider
    after(:create) {|course| create_list(:session, 2, course: course) }
  end
end

FactoryGirl.define do
  factory :session do
    name 'Winter Session'
    description 'Snowboarding 101'
    price 150
    class_size 4
    course
    location
  end
end

FactoryGirl.define do
  factory :location do |l|
    l.sequence(:name) { |n| "location_#{n}"}
  end
end

我也更新了我的测试:

  test 'should return a list of unique locations' do
    provider = create(:provider)
    assert_equal provider.unique_locations, %w[location_1 location_2 location_3 location_4]
  end

这成功创建了4个不同的位置。