Rails 4自动生成RSpec测试删除失败,即使该功能在开发中工作

keb*_*keb 3 rspec ruby-on-rails ruby-on-rails-4

这是自动生成的Rails 4中的destroy操作测试,作为规范的一部分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
Run Code Online (Sandbox Code Playgroud)

这是我在控制器中得到的,再次非常标准:

def destroy
  @vehicle = Vehicle.find(params[:id])
  @vehicle.destroy
  flash[:notice] = "Vehicle has been deleted"
  redirect_to vehicles_url
end
Run Code Online (Sandbox Code Playgroud)

这在应用程序本身中运行得很好 - 当您删除车辆时,它会重定向回veh_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)>'
Run Code Online (Sandbox Code Playgroud)

任何人都可以指出我可能会发生什么,使测试失败?谢谢你的帮助!

编辑:这里有一些关于可能影响事物的过滤器之前的其他信息.在veh_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
Run Code Online (Sandbox Code Playgroud)

现在,如果我尝试运行规范,我收到此语法错误:

/home/kathryn/testing/spec/controllers/vehicles_controller_spec.rb:150: syntax error, unexpected '\n', expecting => (SyntaxError)

第150行指的是第一个规范中的行delete :destroy,其中进行了更改.

Cyb*_*fox 5

您很可能遇到授权错误.尝试在任一测试中添加操作flash[:alert].should == nil后添加delete.如果您遇到授权问题,您将获得类似"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/>.
Run Code Online (Sandbox Code Playgroud)

授权失败的典型实现重定向到根路径.

我个人并不喜欢, valid_session处理登录的方法.如果你正在使用Devise,你应该使用他们的测试助手并适当地登录.例如

describe VehiclesController do
  include Devise::TestHelpers

  before(:each) do
    sign_in FactoryGirl.create(:user)
  end

  . . .
Run Code Online (Sandbox Code Playgroud)

然后(这很重要!)删除所有, valid_session参数,否则它们将覆盖设备为您设置的会话sign_in.

这是最简单的形式; 如果某些用户可以(例如)删除而其他用户不能删除,则仍然会失败,因此对于这些情况,您可能希望创建单独的describe "Admin users can" do... end测试块,并与管理员用户before(:each)进行调用sign_in.

我希望有所帮助,祝你好运!