2014-11-14 60 views
1

我使用Rails 4.1.7,Rspec 3.0.4與FactoryGirl和postgresql ActiveRecord數據庫。FactoryGirl.update實際上並沒有更新關聯對象

我想測試一個方法,找到一個關聯的模型,然後更新該模型中的列。這個測試很粗糙,但它使所有必要的協會(我檢查撬)。調用該方法時,期望值將繼續返回nil(因爲該列默認爲零,但應更新爲日期時間)。下面是代碼:

post_picture_spec.rb

require 'rails_helper' 

RSpec.describe ModelName::PostPicture, :type => :model do 

    describe 'update_campaign method' do 

    context 'when the picture is tied to a campaign' do 

     before do 
     @campaign = FactoryGirl.create(:campaign) 
     @campaign.media << @picture1 = FactoryGirl.create(:picture, posted: true, time_scheduled: Date.parse('2014-07-15 18:00:00'), time_posted: Date.parse('2014-07-15 18:00:00')) 
     @campaign.media << @picture2 = FactoryGirl.create(:picture, posted: true, time_scheduled: Date.parse('2014-08-20 19:00:00'), time_posted: Date.parse('2014-08-20 19:00:00')) 
     end 

     it 'should update first item in campaign' do 
     # pending("FactoryGirl update issue") 
     ModelName::PostPicture.send(:update_campaign, @picture) 
     expect(@campaign.time_started).to eq(@picture.time_posted) 
     end 

    end 

end 

圖片工廠

FactoryGirl.define do 
    factory :picture do 
    time_approved { Date.parse('2014-08-22 17:00:00') } 
    time_posted { Date.parse('2014-08-22 17:00:00') } 
    time_scheduled { Date.parse('2014-08-22 17:00:00') } 
    processed true 
    end 
end 

post_picture.rb

class ModelName::PostPicture 

    def self.call(id) 
    [collapsed] 
    end 

private 

     def self.update_campaign(picture) 
     campaign = picture.campaign 
     campaign_pictures = campaign.pictures.sort_by(&:time_scheduled) 
      campaign.update(time_started: picture.time_posted) if campaign_pictures.first == picture 
      campaign.update(time_completed: picture.time_posted) if campaign_pictures.last == picture 
     end 
end 

錯誤:

Failure/Error: expect(@campaign.time_started).to eq(@picture1.time_posted) 

    expected: 2014-07-15 00:00:00.000000000 +0000 
     got: nil 

    (compared using ==) 
+0

我被'update_campaign'弄糊塗了。爲什麼這是一個類方法?另外,爲什麼使用'send'而不是直接調用方法? – zetetic 2014-11-14 23:09:17

+0

^發送被使用,因爲它是一種私人方法。 – user3390658 2014-11-14 23:45:12

+0

你確定嗎?類方法必須使用'private_class_method'變成私有的。它肯定看起來應該是一個實例方法,如果'campaign_pictures'是一個關聯。也許你可以添加更多的相關代碼? – zetetic 2014-11-15 00:00:47

回答

3

您的@campaign變量在修改之前已經加載,所以您需要在檢查新值之前重新加載它。

it 'should update first item in campaign' do 
    ModelName::PostPicture.send(:update_campaign, @picture) 
    @campaign.reload 
    expect(@campaign.time_started).to eq(@picture.time_posted) 
end 
+0

這修正了它!謝謝! – user3390658 2014-11-15 07:15:35

2

我會建議,加入該協會爲廣告活動中factory_girl圖片。我認爲問題在於,當您在活動記錄對象上使用<<時,實際上並未創建關聯。

我會嘗試在update_campaign方法中包括pry gem和binding.pry以查看模型是否正確創建。另外,我還會使用let語法來代替before do中的所有內容,只是可重用性。

+0

我把binding.pry放在update_campaign方法的第4行 pry> campaign_pictures =>#[<圖片ID:445>, #<圖片ID:446 >] 撬 > campaign.time_started =>零 撬 >運動 #<廣告系列ID:434,time_scheduled: 「2014年8月22日00:00:00」,time_started:無,time_completed:無,草案:無> pry> campaign。media => [<媒體ID:475,time_scheduled:「2014-07-15 00:00:00」,time_posted:「2014-07-15 00:00:00」,campaign_id:434,posted:true>, <媒體ID:476,time_scheduled:「2014-08-20 00:00:00」,time_posted:「2014-08-20 00:00:00」,campaign_id:434,posted:true>] – user3390658 2014-11-14 23:44:05

+0

^抱歉在我輸入時沒有出現很好的縮進:\ – user3390658 2014-11-14 23:45:40

+0

您傳入的圖片看起來不像它具有time_started屬性。在ruby中'private'也不能像你認爲的那樣在類方法上工作。 [這是一個很好的解釋/例子](http://stackoverflow.com/questions/4952980/creating-private-class-method) – 2014-11-15 05:04:41

相關問題