2016-10-25 8 views
1

私はapplication_controller.rbにメソッドのテストを書いていて、適切なテストを書くのに問題があります。このアプリはRails 3.2.17上に構築されています。Rspec RailsがJSONオブジェクトの値を設定しています

object.rb

def previously_purchased? 
    return JSON.parse(self.features)['key']['previously_purchased'] if self.features 
end 

application_controller.rb

def include_bar? 
    url_param = params[:keyword] || cookies[:keyword] 
    @keyword_object = Object.find_by_url(url_param) 
    if @keyword_object.previously_purchased? && !cookies[:prior_purchase] 
     @keyword_object = nil 
     return 
    end 
end 

factories.rb

factory: object do 
    url_param 'TEST' 
end 

application_controller_spec.rb

#this was the most recent test I tried 

context 'URL parameter keyword is present or keyword cookie is present' do 
    context 'object is displayed only to previously purchased' do 
    before(:each) do 
     @saved_object = create :object 
     @other_object = JSON.parse(@saved_object.features) 
     @other_object['key']['previously_purchased'] = true 
     @new_object = @other_object.to_json 
     request.cookies[:prior_purchase] = 'sub' 
     get :index 
    end 

    it 'finds object' do 
     expect(assigns(:keyword_object)).to be_nil 
    end 
    end 
end 

これは私がtrueにpreviously_purchased値を設定することができませんでしたような方法で、理にかなって、次のエラー

Failure/Error: @other_object = JSON.parse(@saved_nanobar.features)
TypeError: no implicit conversion of nil into String

を返します。

私はまた、[]

context 'object is displayed only to previously purchased' do 
    before(:each) do 
    @saved_object = create :object 
    @saved_object.features['key']['previously_purchased'] = true 
    request.cookies[:prior_purchase] = 'sub' 
    get :index 
    end 

    it 'finds object' do 
    expect(assigns(:keyword_object)).to be_nil 
    end 
end 

Failure/Error: @saved_object.features['key']['previously_purchased'].to_json = true
NoMethodError: undefined methodを試してみました」nilのために:私は一種の私のテストを修正する十分理解しなくNilClass`

。私は自分の質問を書いたり書き込んだりするときに、終わりなどの文法を省いているかもしれないので、親切に忍耐してください。

これは長い間私をブロックしており、私は何か助けていただければ幸いです。私はさらに私を導くためのリソースを見つけることができませんでした。あなたが私の質問を変更/明確にするために必要な場合や、より多くの情報が必要な場合は、私に知らせてください。

+0

なぜあなたは 'object.rb'というファイルを持っていますか? 'Object'はコアRubyクラスであり、任意に追加してはいけません。ここでJSONがどのように影響するかについても明確ではありません。パラメータを受け取っている場合、Railsはそれらを解析します。JSON形式のものをデータベースに格納する場合は、 'serialize'を使ってそれを処理できます。 – tadman

+0

それはモデルであり、実際にはobject.rbという名前ではありません。できるだけジェネリックとして質問をするように変更しました。各オブジェクトには列属性があり、列属性の1つはJSONオブジェクトとして保存されます。 – Horatio

+0

ここではあまりにも一般的になってしまったと思います。コンテキストがありません。 – tadman

答えて

0

object.featuresにはJSONが必要です。セットアップこのようなあなたのオブジェクト:

@saved_object = create(
    :object, features: "{ \"key\": { \"previously_purchased\": true} }" 
) 
+0

ありがとう!これはうまくいった!! – Horatio

0

は、列のJSONとして保存した場合、あなたはすべての混乱の世話をするserializeを、使用する必要があります。

class MyModel < ActiveRecord::Base 
    serialize :features, JSON 
end 

次に、あなたが他のどのとしてこれを操作することができます手動で解除するために必要とすることなく、構造や再シリアライズ:

model = MyModel.new 
model.features = { key: { previously_purchased: true } } 
model.save 

は、その後、あなたはこれを行うことができます。

def previously_purchased? 
    if (self.features) 
    !!self.features.dig('key', 'previously_purchased') 
    else 
    false 
    end 
end 

二重否定(!!)を使用してその値をブール値として強制し、Ruby 2.3.1 digメソッドを使用してハッシュをナビゲートします。

+0

私はこれが好きです、それは本当にきれいです。同様の方法で私のメソッドをリファクタリングします。 – Horatio

関連する問題