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



这是 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内部发生了什么,但这不可能是正确的。

最新更新