强制数据库更新失败

时间:2015-06-05 15:56:33

标签: ruby-on-rails ruby unit-testing

我正在测试一个控制器,并希望强制数据库更新失败,以验证我的错误处理是否正常工作。我对rails很新,所以如果我没有遵循所有最佳实践,我会道歉。以下是相关代码:

代码不完整,专注于与此问题相关的重要部分。

控制器:

class SomeController < ApplicationController

  ...

  # relevant actions
  def enable
    able true
  end

  def disable
    able false
  end

  ...

  private 

  def able (b)
    ...
    # @dbobject will be set in a 'before_filter' function
    if @dbobject.update_attribute(enabled: b)
      # do some stuff
    else # <------ need to force execution of this block
      # error handling, logging, boring stuff
      redirect_to @dbobject
    ...
  end

  ...

end

测试

class SomeController::AbleTest < ActionController::TestCase
  tests SomeController

  setup
    # create @dbobject
  end

  test 'redirect occurs on update fail' do
    get :enable, id: @dbobject
    assert_redirected_to @dbobject
  end 

  ...

end

我还在SomeController::AbleTest中进行了需要update_attribute正常工作的测试,因此我宁愿远离完全覆盖该方法。如果访问此记录或类似的东西,有没有办法强制db引发异常?我无法直接从测试类调用able方法,因为它很大程度上依赖于各种before_filter方法设置的实例变量,而且感觉太像打架而不能使{{1并自动运行这些方法。

2 个答案:

答案 0 :(得分:0)

尝试使用mocha gem。您可以暂时存根update_attributes,以便返回false

dbobject.stubs(:update_attributes).returns(false)

请注意,dbobject与您在测试中传递给@dbobject的{​​{1}}相同。您必须存根获取控制器中记录的代码。这比Yule get的方式更麻烦,所以先尝试一下。

答案 1 :(得分:0)

您可以使用存根。查看mocha

DBObject.any_instance.stubs(:update_attribute).returns(false)

这意味着只要你能在任何DBObject实例上使用update_attribute,它就会返回false,然后将你发送到else。所以整个代码将是:

 test 'redirect occurs on update fail' do
    DBObject.any_instance.stubs(:update_attribute).returns(false)
    get :enable, id: @dbobject
    assert_redirected_to @dbobject
  end