【问题标题】:Testing unit with skip_before_action does not unset after using TDD使用 TDD 后没有取消设置 skip_before_action 的测试单元
【发布时间】:2018-06-07 10:11:56
【问题描述】:

我正在使用 Rails 5.2 并进行一些测试。我正在尝试使用ActionController::TestCase 进行单元测试,发现@controller.class.skip_before_action :verify_user 在进入下一个测试单元方法之前不会自动重置控制器。

现在,由于每次运行时 rails 测试都是随机的,因此某些单元有时会失败,有时不会失败。我认为它期待 HTTP 401,但我得到了 200。导致控制器忽略 before_action :verify_user

我可以在每个单元的末尾设置@controller.class.before_action :verify_user(它可以工作!)但它不应该是测试 sys 以在每次运行之前重置上下文的代表吗?

提供我的代码片段:

class ApiSiteMetricsTest < ActionController::TestCase
  tests Api::SiteMetricsController

  def test_1_index
    @controller.class.skip_before_action :verify_user,raise: false

    get "index",  params:{ 
        "format"=>"json",
        "site_metric_value"=>{
            "site_metric_id"=>2403, 
            "date_acquired"=>"2018-03-14T01:44:00+05:30", 
            "site_id"=>3840, 
            "lab_device_details"=>"", 
            "comment"=>"", 
            "sender_affiliation"=>"", 
            "float_value"=>""
        }
    }
    assert_response :success
    File.open("#{Rails.root}/del.html", "wb") { |f| f.write(@response.body) }        
    #Do I have to do this o every test?
    #@controller.class.before_action :verify_user
  end
  ...

【问题讨论】:

  • 你没有一些配置可以在每次测试后启用上下文重置吗?使用 rspec 可以在 spec_helper.rb 中使用 config.use_transactional_fixtures = true 完成。同样使用 rspec 你有 before(:each) 和 after(:each) 回调将你的 skip 和 before_action 放入,避免手动将其粘贴到每个测试中
  • config.use_transactional_fixtures 在这里无关紧要。

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


【解决方案1】:

您绝对正确,每个测试都应在运行后重置系统状态。测试应该是完全独立的——这正是它们以随机顺序运行的原因(默认情况下)。

对于大多数事情 - 例如数据库事务 - 测试框架可以为您处理。但是还有无数其他方法可以改变环境。测试框架不能总是遮住你的后背。

例如,如果您的测试更改了ENV 变量怎么办?或致电Timecop.freeze?还是通过第二个数据库连接添加数据库记录?或者设置一个全局变量? ...

有时,您需要手动重置状态!

在这种情况下,我会这样做:

class ApiSiteMetricsTest < ActionController::TestCase
  tests Api::SiteMetricsController

  def test_1_index
    @controller.class.skip_before_action :verify_user,raise: false

    # ...

    ensure

    @controller.class.before_action :verify_user
  end
end

ensure 存在,因此即使此测试失败,状态也应重置 - 因此不会影响 其他 测试是否失败。

在某些情况下,您可能会发现使用MiniTestsetupteardown 方法来提供此功能很方便。 (相当于rspec 中的beforeafter 钩子)。

【讨论】:

  • 作为替代方案,您可以在此测试中只使用stub verify_user 方法,而不是更改类的定义。
  • 有没有办法只重置@controller.class定义?就像在setup 中调用@controller = Api::PeopleController.new 应该已经重新加载了类def
猜你喜欢
  • 2011-04-19
  • 2023-03-05
  • 2011-03-14
  • 2013-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多