2017-03-02 179 views
0

我剛剛構建了一個Rails 5新應用程序--api。我搭建了一個模型並添加了一個枚舉。Rails 5腳手架和Rspec控制器測試enum測試

class Track < ApplicationRecord 
    enum surface_type: [:asphalt, :gravel, :snow], _prefix: true 
end 

一個腳手架控制器測試的是這樣的:

context "with invalid params" do 
    it "assigns a newly created but unsaved track as @track" do 
    post :create, params: {track: invalid_attributes}, session: valid_session 
    expect(assigns(:track)).to be_a_new(Track) 
    end 
end 

我加在上面無效的屬性:

let(:invalid_attributes) {{ 
    "name": "Brands Hatch", 
    "surface_type": "wood" 
    }} 

,改變了預期行此

expect(assigns(:track)).not_to be_valid 

但是測試d oes不起作用,因爲如果您傳遞了無效的枚舉,則無法創建Track對象。

控制器動作:

def create 
    @track = Track.new(track_params) 

    if @track.save 
     render json: @track, status: :created 
    else 
     render json: @track.errors, status: :unprocessable_entity 
    end 
    end 

那麼,如何測試這個方案?

+0

這是不可能的'create'對象,但你可以實例化它...使用'.new'然後'#update_attributes'(或'#'save'#assign_attributes')。你可以顯示你的控制器創建代碼? – SteveTurczyn

+0

謝謝,我添加了控制器代碼。我猜測誰寫腳手架測試沒有考慮這個邊緣案例。 – rmcsharry

+0

我不知道如何解釋我的意思 - 但腳手架測試設置爲使用「有效」和「無效」屬性......這裏的含義是爲了測試驗證(如validates_presence_of)。枚舉不使用validates_presence_of,所以這就是我稱之爲邊緣情況的原因。我想我必須寫一些其他類型的測試,但我不知道什麼,感嘆。 :( – rmcsharry

回答

1

通過正常驗證可以捕獲無效:surface_type的一種方法是截取分配。

class Track < ApplicationRecord 
    enum surface_type: [:asphalt, :gravel, :snow], _prefix: true 
    attr_accessor :bad_surface_type 
    validate :check_surface_type 

    def surface_type=(surface) 
    super surface 
    rescue 
    self.bad_surface_type = surface 
    super nil 
    end 

    private 

    def check_surface_type 
    errors.add(:surface_type, "the value #{bad_surface_type} is not valid") if bad_surface_type 
    end 
end 
+0

確實很聰明我剛剛發現了這個問題,表明這是Rails上的一個問題Github http://stackoverflow.com/questions/37177893/rails-enum-validation-not-working-but-raise-argumenterror?noredirect=1&lq=1並閱讀該問題我發現推薦使用枚舉正在跟蹤內部應用程序STATE ....不要在應用程序之外暴露他們OMG這對我來說是新聞 – rmcsharry

+0

Huh。也是我的新聞我不需要擔心這個,因爲我的枚舉暴露給用戶選擇,我使用' f.select'並控制提供給最終用戶的選項我從未覺得需要測試無效的選項。 – SteveTurczyn

+0

是的,這就是提出異常而不是驗證錯誤的原因。永遠不可能設置無效值。除了當你正在建立一個API - 這是當客戶端可以發送無效值。所以我可能會將枚舉轉換爲模型,從長遠來看更易於維護。 – rmcsharry