Rspec Rails 在 JSON 对象中设置一个值
Rspec Rails setting a value in a JSON object
我正在为 application_controller.rb 中的方法编写测试,但在编写正确的测试时遇到了问题。该应用程序基于 Rails 3.2.17.
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
这个returns下面的错误
Failure/Error: @other_object = JSON.parse(@saved_nanobar.features)
TypeError: no implicit conversion of nil into String
这是有道理的,因为我无法将值 previously_purchased 设置为 true。
我也试过了
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`
我有点理解,但还不足以修复我的测试。在形成和编写我的问题时,我可能遗漏了结尾或一些其他语法,所以请耐心等待。
这一直困扰着我,我很感激任何帮助。我无法找到资源来进一步指导我。如果您需要我修改/澄清我的问题或需要更多信息,请告诉我,我会马上处理。
您的 object.features
需要包含一个 JSON。像这样设置你的对象:
@saved_object = create(
:object, features: "{ \"key\": { \"previously_purchased\": true} }"
)
如果列保存为 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
方法来导航散列。
我正在为 application_controller.rb 中的方法编写测试,但在编写正确的测试时遇到了问题。该应用程序基于 Rails 3.2.17.
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
这个returns下面的错误
Failure/Error: @other_object = JSON.parse(@saved_nanobar.features)
TypeError: no implicit conversion of nil into String
这是有道理的,因为我无法将值 previously_purchased 设置为 true。
我也试过了
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`
我有点理解,但还不足以修复我的测试。在形成和编写我的问题时,我可能遗漏了结尾或一些其他语法,所以请耐心等待。
这一直困扰着我,我很感激任何帮助。我无法找到资源来进一步指导我。如果您需要我修改/澄清我的问题或需要更多信息,请告诉我,我会马上处理。
您的 object.features
需要包含一个 JSON。像这样设置你的对象:
@saved_object = create(
:object, features: "{ \"key\": { \"previously_purchased\": true} }"
)
如果列保存为 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
方法来导航散列。