Ruby on rails 如何使更新在rspec中失败?

Ruby on rails 如何使更新在rspec中失败?,ruby-on-rails,rspec,tdd,bdd,Ruby On Rails,Rspec,Tdd,Bdd,我成功地为以下更新方法编写了测试: def update @user = User.find(params[:id]) @user.update_attributes!(user_update_params) render :nothing => true end context "update user" do it "should update a user based on valid info" do @factory

我成功地为以下更新方法编写了测试:

  def update
    @user = User.find(params[:id])
    @user.update_attributes!(user_update_params)
    render :nothing => true
  end

  context "update user" do   
    it "should update a user based on valid info" do
      @factory = FactoryGirl.create(:user)
      put :update, :id => @factory.id, :user => {
         :name => 'sample_user', :user_name => 'sample_user',
         :email => 'sample@gmail.com', :email_confirmation => 'sample@gmail.com',
         :password => 'SamplePassword', :password_confirmation => 'SamplePassword',
         :bio => 'apple sauce', :picture_url => 'http://google.ca'
      }
      assert_equal "sample_user", assigns(:user).name
    end
    it "should not update a user based on invalid info" do
      @factory = FactoryGirl.create(:user)
      put :update, :id => @factory.id, :user => {
         :name => 'sample_user', :user_name => 'sample_user',
         :email => 'sample@gmail.com', :email_confirmation => 'sample@gmail.com',
         :password => 'SamplePassword', :password_confirmation => 'asdasdasd',
         :bio => 'apple sauce', :picture_url => 'http://google.ca'
      }
      assigns(:user).valid?.should == false
    end
  end
但我真的不知道如何写相反的东西。我的意思是我可以做
:password\u confirmation=>'asdasd'
,但当我尝试时-它表明我的密码确认与密码不匹配,然后测试失败0它应该通过-这可以在第二次测试中看到


有什么想法吗?测试应通过,但输入内容的有效性应为false。

首先,您不测试控制器规范中的任何验证。这就是模型规范的目的。测试关联和验证的一个好方法是使用gem

所以回到你的规格;看看你的
update
方法,我将规范写为:

  • 首先编写快乐路径的示例(找到用户且参数有效)
  • 处理在
    DB
    中找不到具有给定
    id
    用户
    的情况
  • 处理
    用户
    实例希望使用无效参数进行更新的情况
  • 我通常关注具有指定属性的方法调用和实例变量的赋值

    希望能有帮助

    
    context "update user" do
      let(:user_id) { 63 }
      let(:user)    { FactoryGirl.create :user, id: user_id }
    
      context 'when success' do
        # simplified valid attributes hash
        let(:valid_attributes) { { :name => user_name } }
        let(:user_name) { 'sample_user' }
    
        it 'should find the user by id passed in params' do
          User.should_receive(:find).with(user_id).and_return(user)
    
          put :update, :id => user_id, :user => valid_attributes
    
          assigns(:user).should eq(user)
        end
    
        it "should update a user based on valid info" do
          put :update, :id => user_id, :user => valid_attributes
    
          expect(assigns(:user).name).to eq(user_name)
        end
      end
    
      context 'when failure' do
        let(:invalid_attributes) { {} }
    
        context 'when a user is not found' do
          let(:user_id) { nil }
    
          it 'raises ActiveRecord::RecordNotFound exception when no user is found'
            User.should_receive(:find).with(user_id).and_raise(ActiveRecord::RecordNotFound)
    
            put :update, :id => user_id, :user => invalid_attributes
          end
        end
    
        context 'when a user is found' do
          it "raises ActiveRecord::RecordInvalid exception when updated with invalid attributes" do
            User.any_instance.should_receive(:update_attributes!).with(invalid_attributes).and_raise(ActiveRecord::RecordInvalid)
    
            put :update, :id => user_id, :user => invalid_attributes
          end
        end
      end
    end
    

    您是否尝试获取记录并测试其当前属性?就像测试它是否仍然有默认属性并且没有正确更新一样

    差不多

    it "should not update a user based on invalid info" do
      @factory = FactoryGirl.create(:user)
      put :update, :id => @factory.id, :user => {
         :name => 'sample_user', :user_name => 'sample_user',
         :email => 'sample@gmail.com', :email_confirmation => 'sample@gmail.com',
         :password => 'SamplePassword', :password_confirmation => 'asdasdasd',
         :bio => 'apple sauce', :picture_url => 'http://google.ca'
      }
      User.first.name.should == 'the factory default name'
      User.first.name.should_not == 'sample_user'
    end
    

    我解决这个问题的方法是

    it "should not update a user based on invalid info" do
      assert_raises(ActiveRecord::RecordInvalid) do
        @factory = FactoryGirl.create(:user)
        put :update, :id => @factory.id, :user => {
           :name => 'sample_user', :user_name => 'sample_user',
           :email => 'sample@gmail.com', :email_confirmation => 'sample@gmail.com',
           :password => 'SamplePassword', :password_confirmation => 'asdasdasd',
           :bio => 'apple sauce', :picture_url => 'http://google.ca'
        }
      end
    end
    

    这是因为-当密码不匹配时,我们无法向数据库提交数据。

    如果您使用
    更新\u属性异常将在出现错误时引发,所以您可以编写一个测试来检查是否引发了异常。(我不再使用RSpec,所以我不记得要使用的测试助手的名称)问题-它声明密码不匹配,因此永远不会涉及用户。第一个问题是-活动记录找不到id为零的记录