2016-07-28 40 views
2

當請求規範失敗時(錯字或其他異常),我們當前會面臨一個問題,它會影響實際上應該不受影響的其他請求規範。問題是,我們用很多的寶石,所以我試圖創建一個最小的再現應用程序(沒有成功,https://github.com/tak1n/reproduction請求規範順序依賴失敗(在登錄時爲創建用戶更新而創建的SQL錯誤)

詳細的問題:

我們有我們需要登錄的用戶的請求規範。對於用戶認證,我們使用設計,因此我們使用Warden :: Test :: Helpers在請求規格中登錄用戶。在用戶登錄時,設計會自動更新一些與用戶相關的屬性(last_sign_in_at,last_sign_in_ip等)。

這裏的問題是,當它試圖保存用戶執行此操作時,最終結果是INSERT INTO用戶而不是UPDATE用戶,因此它崩潰。

這裏是我們的應用程序爲例規格:

require 'rails_helper' 

RSpec.describe 'Suggestions API' do 
    let(:user) { FactoryGirl.create(:user, :professional) } 

    before do 
    login(user) # same as in https://github.com/tak1n/reproduction/blob/master/spec/support/request_macros.rb#L6 
    end 

    describe '/suggestions.json', :vcr do 
    context 'with non saved filter' do 
     # some setup stuff here (setup proper objects in db) 

     # also params are defined here through let(:params) { ... } 

     it 'returns proper suggestions' do 
     Suggestion.refresh! 

     get '/suggestions.json', paramst 

     expect(json.count).to eq(2) 

     expect(json.first['id']).to eq(sug2.id) 
     expect(json.second['id']).to eq(sug1.id) 
     end 
    end 

    context 'with saved filter' do 
     # some setup stuff here (setup proper objects in db) 

     # also params are defined here through let(:params) { ... } 

     it 'returns proper suggestions' do 
     Suggestion.refresh! 

     get '/suggestions.json', params 

     expect(json.count).to eq(2) 

     expect(json.first['id']).to eq(sug2.id) 
     expect(json.second['id']).to eq(sug1.id) 
     end 
    end 
    end 
end 

這樣做的結果應該是第一規格失敗,因爲錯字paramst,其中它,但它也影響到第二規格:

這裏是規範運行:https://gist.github.com/tak1n/102c1aa121b66e0ab56602b76f911ec0

我試圖深入挖掘,發現的邏輯是否保存創建或更新記錄取決於https://github.com/rails/rails/blob/master/activerecord/lib/active_record/persistence.rb#L85

接下來我試圖輸出什麼@new_record在這種情況下。

def new_record? 
    sync_with_transaction_state 
    puts "New record: #{@new_record}" if self.class == User 
    @new_record 
end 

我得到了以下幾點:https://gist.github.com/tak1n/330560a3a108abc8fce4d105a48ac444

當規格不同的順序運行(非失敗的第一個,然後在它拼寫錯誤或異常SPEC)我得到這個:https://gist.github.com/tak1n/6eb24693226d8e6a713c0865ea1bebd5

這裏的區別是「工作」規格運行New Record: <boolean>是不同的。當具有異常的規範運行之前,新記錄突然變爲true,因此它會生成SQL以創建新記錄。

接下來我假設一些寶石導致了這個問題,最有可能的是我認爲這將是database_cleaner,但在複製中,我做的或多或少是相同的,它在那裏工作。

問題是我真的被困在調試中,並不確定在哪裏繼續。此外,我不確定哪個寶石或我們的代碼本身造成這種情況。

如果您需要更多詳細信息,請隨時提出任何問題,提前致謝。

+0

你有沒有嘗試將'login(user)'調用放在你的'it'塊中?我認爲這將確保他們運行並創建用戶,即使在塊中降低了引發的異常。 – DiegoSalazar

+0

@diego。greyrobot是的我試圖把用戶創建和用戶登錄到'it'塊中,但是與'before do'基本相同的結果'before(:each)do'因此它已經爲每個spec示例。 –

回答

相關問題