Rspec 控制器规范声明函数 ios 未调用
Rspec controller spec claims function ios not called
我正在测试我的一个控制器,并试图存根函数调用,但没有成功。这是函数:
def fetch_typeform_response
hp = HealthProfile.find(params[:id])
form = TypeformService.new('x')
response = form.getResponse("query=#{ hp[:id] }")
if response['total_items'] != 1
if response[:response_id].present?
response = form.getResponse("included_response_ids=#{ hp[:response_id] }")
end
end
if response['total_items'] == 1
response = response['items'].first
health_profile = HealthProfile.map_typeform_response(response)
if health_profile.save
health_profile.reload
redirect_to health_profile_path(health_profile), notice: "Successfully updated the health profile response."
return
end
end
redirect_to health_profiles_path, notice: "We could not locate the health profile."
end
在我的测试中,我去掉了 :getResponse
和 :map_typeform_response
,因为它们涉及外部 API:
it "expects to fetch typeform response" do
new_hp = build(:health_profile)
new_hp_after_mapping = build(:health_profile)
allow_any_instance_of(TypeformService).to receive(:getResponse).and_return({ 'total_items': 1, 'items': [ new_hp ] }.as_json)
allow_any_instance_of(HealthProfile).to receive(:map_typeform_response).and_return(new_hp_after_mapping)
get :fetch_typeform_response, params: { id: @hp.id }
expect(response).to redirect_to(health_profile_path(@hp.id))
end
但我收到错误消息:HealthProfile does not implement #map_typeform_response
。
如果删除存根行,我会看到错误:
Failure/Error: p "Using health_profile_id: #{response['hidden']['id']}"
NoMethodError:
undefined method `[]' for nil:NilClass
它发生在 :map_typeform_response
函数内部(很明显它被调用了!)。知道为什么会发生这种情况吗?
您正在 class HealthProfile
而不是 class 的实例上调用 map_typeform_response
方法。
改变
allow_any_instance_of(HealthProfile).to receive(:map_typeform_response).and_return(new_hp_after_mapping)
到
allow(HealthProfile).to receive(:map_typeform_response).and_return(new_hp_after_mapping)
发生这种情况是因为 rspec 阻止您模拟或存根一个在真实对象上不存在的方法。默认为真,因为 Rails 4.
RSpec.configure do |config|
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
end
更多建议
我还建议将 new_hp
和 new_hp_after_mapping
变量的构建移动到 let
let(:new_hp) { build(:health_profile) }
let(:new_hp_after_mapping) { build(:health_profile) }
将存根移动到 before
before do
allow_any_instance_of(TypeformService).to receive(:getResponse).and_return({ 'total_items': 1, 'items': [ new_hp ] }.as_json)
allow(HealthProfile).to receive(:map_typeform_response).and_return(new_hp_after_mapping)
end
所以你的测试看起来像
it "expects to fetch typeform response" do
# make sure variable @hp intialized in your test.
get :fetch_typeform_response, params: { id: @hp.id }
expect(response).to redirect_to(health_profile_path(@hp.id))
end
我正在测试我的一个控制器,并试图存根函数调用,但没有成功。这是函数:
def fetch_typeform_response
hp = HealthProfile.find(params[:id])
form = TypeformService.new('x')
response = form.getResponse("query=#{ hp[:id] }")
if response['total_items'] != 1
if response[:response_id].present?
response = form.getResponse("included_response_ids=#{ hp[:response_id] }")
end
end
if response['total_items'] == 1
response = response['items'].first
health_profile = HealthProfile.map_typeform_response(response)
if health_profile.save
health_profile.reload
redirect_to health_profile_path(health_profile), notice: "Successfully updated the health profile response."
return
end
end
redirect_to health_profiles_path, notice: "We could not locate the health profile."
end
在我的测试中,我去掉了 :getResponse
和 :map_typeform_response
,因为它们涉及外部 API:
it "expects to fetch typeform response" do
new_hp = build(:health_profile)
new_hp_after_mapping = build(:health_profile)
allow_any_instance_of(TypeformService).to receive(:getResponse).and_return({ 'total_items': 1, 'items': [ new_hp ] }.as_json)
allow_any_instance_of(HealthProfile).to receive(:map_typeform_response).and_return(new_hp_after_mapping)
get :fetch_typeform_response, params: { id: @hp.id }
expect(response).to redirect_to(health_profile_path(@hp.id))
end
但我收到错误消息:HealthProfile does not implement #map_typeform_response
。
如果删除存根行,我会看到错误:
Failure/Error: p "Using health_profile_id: #{response['hidden']['id']}"
NoMethodError:
undefined method `[]' for nil:NilClass
它发生在 :map_typeform_response
函数内部(很明显它被调用了!)。知道为什么会发生这种情况吗?
您正在 class HealthProfile
而不是 class 的实例上调用 map_typeform_response
方法。
改变
allow_any_instance_of(HealthProfile).to receive(:map_typeform_response).and_return(new_hp_after_mapping)
到
allow(HealthProfile).to receive(:map_typeform_response).and_return(new_hp_after_mapping)
发生这种情况是因为 rspec 阻止您模拟或存根一个在真实对象上不存在的方法。默认为真,因为 Rails 4.
RSpec.configure do |config|
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
end
更多建议
我还建议将 new_hp
和 new_hp_after_mapping
变量的构建移动到 let
let(:new_hp) { build(:health_profile) }
let(:new_hp_after_mapping) { build(:health_profile) }
将存根移动到 before
before do
allow_any_instance_of(TypeformService).to receive(:getResponse).and_return({ 'total_items': 1, 'items': [ new_hp ] }.as_json)
allow(HealthProfile).to receive(:map_typeform_response).and_return(new_hp_after_mapping)
end
所以你的测试看起来像
it "expects to fetch typeform response" do
# make sure variable @hp intialized in your test.
get :fetch_typeform_response, params: { id: @hp.id }
expect(response).to redirect_to(health_profile_path(@hp.id))
end