这是 Rails 4 中销毁操作的自动生成的测试,作为 vehicles_controller.rb
规范的一部分:
describe "DELETE destroy" do
it "destroys the requested vehicle" do
vehicle = Vehicle.create! valid_attributes
expect {
delete :destroy, {:id => vehicle.to_param}, valid_session
}.to change(Vehicle, :count).by(-1)
end
it "redirects to the vehicles list" do
vehicle = Vehicle.create! valid_attributes
delete :destroy, {:id => vehicle.to_param}, valid_session
response.should redirect_to(vehicles_url)
end
end
这是我在控制器中得到的,同样非常标准:
def destroy
@vehicle = Vehicle.find(params[:id])
@vehicle.destroy
flash[:notice] = "Vehicle has been deleted"
redirect_to vehicles_url
end
这在应用程序本身中工作得很好 - 当您删除车辆时,它会重定向回vehicles_url,并且该条目将从数据库中删除。服务器日志看起来也完全正常。但是,当我运行规范时,它们失败如下:
1) VehiclesController DELETE destroy destroys the requested vehicle
Failure/Error: expect {
count should have been changed by -1, but was changed by 0
# ./spec/controllers/vehicles_controller_spec.rb:148:in `block (3 levels) in <top (required)>'
2) VehiclesController DELETE destroy redirects to the vehicles list
Failure/Error: response.should redirect_to(vehicles_url)
Expected response to be a redirect to <http://test.host/vehicles> but was a redirect to <http://test.host/>.
Expected "http://test.host/vehicles" to be === "http://test.host/".
# ./spec/controllers/vehicles_controller_spec.rb:156:in `block (3 levels) in <top (required)>'
谁能指出这里可能发生的事情使测试失败?感谢您的任何帮助!
编辑:这里有一些关于之前可能影响事物的过滤器的其他信息。在vehicles_controller中,由于我使用的是宝石CanCan,所以我在顶部有load_and_authorize_resource
。该控制器也正在测试创建和更新的能力,并且这些规范正在通过,因此我认为这不会干扰,而且它不会因任何与权限相关的消息而失败。也许我需要更改控制器规范顶部的默认let(:valid_session) { {} }
?我不管它,因为正如我所说,除了删除之外,所有其他操作都很好。
进一步编辑:根据下面提供的链接,我将我的规范编辑为:
describe "DELETE destroy" do
it "destroys the requested vehicle" do
vehicle = Vehicle.create! valid_attributes
expect {
delete :destroy, :id => vehicle.to_param, valid_session
}.to change(Vehicle, :count).by(-1)
end
it "redirects to the vehicles list" do
vehicle = Vehicle.create! valid_attributes
delete :destroy, :id => vehicle.to_param, valid_session
response.should redirect_to(vehicles_url)
end
end
现在,如果我尝试运行规范,我会收到以下语法错误:
/home/kathryn/testing/spec/controllers/vehicles_controller_spec.rb:150: syntax error, unexpected 'n', expecting => (SyntaxError)
第 150 行是指第一个规范中以 delete :destroy
开头的行
您很可能遇到授权错误。 尝试在任一测试的delete
操作后添加flash[:alert].should == nil
。 如果遇到授权问题,则在测试失败时会出现类似"You are not authorized to access this page."
。
最大的线索是你的测试也失败了:
Expected response to be a redirect to <http://test.host/vehicles> but was a redirect to <http://test.host/>.
授权失败的典型实现会重定向到根路径。
我个人不喜欢处理登录的, valid_session
方法。 如果您使用的是 Devise,则应使用其测试帮助程序并适当登录。 例如
describe VehiclesController do
include Devise::TestHelpers
before(:each) do
sign_in FactoryGirl.create(:user)
end
. . .
然后(这很重要!(删除所有, valid_session
参数,否则它们将覆盖 Design 使用 sign_in
方法为您设置的会话。
这是最简单的形式;如果某些用户可以(例如(删除而其他人不能,这仍然会失败,因此对于这些情况,您可能希望创建一个单独的describe "Admin users can" do
... end
测试块,并有一个before(:each)
,该使用管理员用户调用sign_in
。
我希望这有所帮助,祝你好运!
Ruby的解析器与内联哈希混淆了。您可能希望:
delete :destroy, {:id => vehicle.to_param}, valid_session
您在将参数传递给delete
时遇到了麻烦。请参阅 http://api.rubyonrails.org/classes/ActionController/TestCase/Behavior.html#method-i-delete 中的方法定义。
您可以使用以下任一方法:
delete :destroy, {id: vehicle.to_param, session: valid_session}
或
delete :destroy, id: vehicle:to_param, session: valid_session
我不确定您传入的最后两个参数在ActionController
内部发生了什么,但这不可能是正确的。