【问题标题】:How can I make an update fail in rspec?如何在 rspec 中使更新失败?
【发布时间】:2013-09-02 17:04:18
【问题描述】:

我设法为以下更新方法编写了一个测试:

  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_confirmation => 'asdasd' 但是当我尝试这样做时 - 它表明我的密码确认与密码不匹配然后测试失败 0 它应该通过 - 这可以在第二个测试中看到

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

【问题讨论】:

  • 如果你使用update_attributes! 异常会在错误时引发,所以你可以编写一个测试来检查是否引发了异常。 (我不再使用 RSpec,所以我不记得要使用的测试助手的名称)

标签: ruby-on-rails rspec tdd bdd


【解决方案1】:

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

类似

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

【讨论】:

  • 这个问题 - 它指出密码不匹配,因此永远不会归结为 User.First jazz
【解决方案2】:

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

回到你的规格;查看您的 update 方法,我会将规范写为:

  1. 先写幸福路径的例子,(找到用户且参数有效)
  2. DB 中找不到带有给定idUser 时处理这种情况,
  3. 处理user 实例想要使用无效参数更新的情况。

我通常会关注带有指定属性的方法调用和实例变量的赋值。

希望对你有帮助。


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

【讨论】:

  • 这个问题 - 活动记录找不到 ID 为 nil 的记录
【解决方案3】:

我解决这个问题的方法是

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

这通过了,因为 - 当密码不匹配时,我们无法将数据提交到数据库。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 2021-09-23
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多