这是我的控制器测试(“spec / controllers / api / tasks_controller_spec.rb”)
require 'spec_helper'
describe Api::TasksController do
before :each do
@quadros = create :cat
@task = Task.new(:content => "Example task for #api")
@quadros.add_task(@task)
end
describe "GET index" do
it "returns a list of all user's tasks" do
get :index, :format => 'json'
expect(response).to eq(User.first.all_tasks)
end
end
end
这是我的Api :: BaseController
class Api::BaseController < ApplicationController
respond_to :json
skip_before_filter :authenticate_user!
end
和Api :: TasksController
class Api::TasksController < Api::BaseController
def index
@tasks = User.first.all_tasks
respond_with @tasks.to_json
end
end
我的其他测试运行正常。
当我运行api测试时,它执行before块,将请求作为json,然后挂起这个查询:
Processing by Api::TasksController#index as JSON
User Load (0.3ms) SELECT `users`.* FROM `users` LIMIT 1
Tag Load (0.3ms) SELECT `tags`.* FROM `tags` WHERE (user_id = 418 AND parent_tag_id IS NOT NULL)
Tag Load (0.2ms) SELECT `tags`.* FROM `tags` WHERE `tags`.`id` IN (NULL)
Tag Load (0.3ms) SELECT `tags`.* FROM `tags` WHERE (user_id = 418 AND parent_tag_id IS NULL)
Task Load (0.7ms) SELECT tasks.* FROM `tasks` JOIN tag_tasks on tasks.id = tag_tasks.task_id WHERE (tag_tasks.tag_id IN (301) OR creator_id = 418) GROUP BY tasks.id ORDER BY tasks.created_at DESC
Completed 200 OK in 99ms (Views: 0.1ms | ActiveRecord: 0.0ms)
User Load (0.3ms) SELECT `users`.* FROM `users` LIMIT 1
Tag Load (0.2ms) SELECT `tags`.* FROM `tags` WHERE (user_id = 418 AND parent_tag_id IS NOT NULL)
Tag Load (0.2ms) SELECT `tags`.* FROM `tags` WHERE `tags`.`id` IN (NULL)
Tag Load (0.2ms) SELECT `tags`.* FROM `tags` WHERE (user_id = 418 AND parent_tag_id IS NULL)
Task Load (0.7ms) SELECT tasks.* FROM `tasks` JOIN tag_tasks on tasks.id = tag_tasks.task_id WHERE (tag_tasks.tag_id IN (301) OR creator_id = 418) GROUP BY tasks.id ORDER BY tasks.created_at DESC
它将永远坐在哪里。
为什么会发生这种情况的任何想法?
答案 0 :(得分:1)
我遇到了类似的问题,看来问题出在您的预期线上:
expect(response).to eq(User.first.all_tasks)
这不是RSpec希望您测试响应体的方式。请注意,in the docs使用了专门的匹配器而不是等号匹配器:
expect(response).to render_template("index")
因此,response
对象(ActionController::TestResponse
)的目的是查询发生了什么,而不是响应正文。所以你的测试应该是这样的:
expect(JSON.parse(response.body)).to eq(User.first.all_tasks)
(请注意,响应正文是一个字符串。)
关于为什么测试挂起而不是完全失败的解释 - 看来这个代码块(lib/rspec/expectations/fail_with.rb:22
gem版本2.14.0中的rspec-expectations
)是罪魁祸首:
if actual && expected
if all_strings?(actual, expected)
if any_multiline_strings?(actual, expected)
message << "\nDiff:" << differ.diff_as_string(coerce_to_string(actual), coerce_to_string(expected))
end
elsif no_procs?(actual, expected) && no_numbers?(actual, expected)
message << "\nDiff:" << differ.diff_as_object(actual, expected)
end
end
all_strings?
,any_multiline_strings?
,no_procs?
和no_numbers?
方法(在同一文件中定义)都会在args.flatten
上调用[actual, expected]
。在这种情况下,我可以告诉问题的是actual
是TestResponse
,这导致flatten
方法本身挂起而不会引发运行时错误。我没有时间进一步调查此问题,但Array.flatten
的来源是here,如果有人有兴趣的话。