我正在使用RSPEC和Factories(使用 工厂女工) 控制器代码:
class JobsController < ApplicationController
before_action :authenticate_member!
before_action :set_job
def complete
@job.status = "completed"
@job.save!
Event.where("job_id = ? AND starts_at > ?", @job.id, DateTime.now).destroy_all
redirect_to scheduler_path
puts @job.inspect
end
def set_job
@job = Job.find(params[:id] || params[:job_id])
end
end
RSPEC代码:
describe JobsController do
login_user
before do
@job=FactoryGirl.create(:job)
end
describe "Complete Action" do
it "sets job status to complete" do
puts @job.inspect
get :complete, :id=>@job.id
@job.status.should eq("Completed")
end
end
错误:
expected: "Completed" got: "pending" (compared using ==)
注意控制器代码的输出是:
#<Job id: 12, name: nil, status: "completed">
所以我知道它在控制器中发生了变化,但为什么它会在工厂女孩中回到“待定”?注2:待定是默认值。 我误解了控制器和工厂女孩之间的关系吗?
请帮帮忙?!
答案 0 :(得分:1)
这里发生的事太多了。
首先,当状态设置为Completed
并且案例为C
时,您不能指望completed
使用大写c
。
其次,有两条puts @job.inspect
行 - 一行在控制器中,另一行在测试中;确保你能够区分两者的输出。
最后,在控制器测试中,在get
语句之后,您需要@job.reload
以确保从数据库更新@job
对象。如果没有@job.reload
,您仍然会看到@job.status
的原始值 - 正确设置为pending
(我假设出厂)
有关为何需要@job.reload
的更全面解释,请参阅https://stackoverflow.com/a/7449957/429758。
完整的控制器测试如下:
describe "Complete Action" do
it "sets job status to complete" do
@job.status.should eq("pending") # Optionally check the original status
get :complete, :id=>@job.id
@job.reload
@job.status.should eq("completed")
end
end
答案 1 :(得分:1)
您应该尝试重新加载@job
:
@job.reload.status.should eq "completed"
请注意,我已将Completed
更改为预期字符串中的completed
。
除此之外,我注意到您使用了before_action
来检索作业,这可以通过不同的方式完成。您也没有检查作业是否已保存,并且始终重定向到scheduler_path
。您可能想要更改它。我会亲自做这样的事情:
class JobsController < ApplicationController
before_action :authenticate_member!
def complete
if job.update_attributes status: :completed
Event.where("job_id = ? AND starts_at > ?", job.id, DateTime.now).destroy_all
redirect_to scheduler_path
else
# do something else, perhaps redirect to scheduler_path with an alert?
end
end
def job
@job ||= Job.find(params[:id] || params[:job_id])
end
end