【问题标题】:Minitest instance variables logged but assertion gets nil记录了 Minitest 实例变量,但断言为零
【发布时间】:2021-06-16 12:06:25
【问题描述】:

minitest 返回Expected nil to be truthy.

控制器动作处理以下语句

@cu = current_user.roleshopusers.where(shop_id: @site.shop_id).first
@cu_role = @cu.try(:role_id)
@cu_buyer = @cu.buyer
Rails.logger.info @cu.inspect
Rails.logger.info @cu.buyer

并且测试日志返回:

#<Roleshopuser id: 434940726, user_id: 7, shop_id: 31, role_id: 1, buyer: true, special_support: false, special_needs: nil, notes: nil, discount: 0.0, created_at: "2021-06-16 13:56:37.288691000 +0200", updated_at: "2021-06-16 13:56:37.288691000 +0200">
true

但是测试,同时返回具有相同方法定义的正确值,

puts current_user.id
puts current_user.roleshopusers.where(shop_id: @site.shop_id).first.buyer
puts @cu.inspect
    assert @cu_buyer

没有可用的实例变量。

7
true
nil

那么这个测试应该怎么写呢?

【问题讨论】:

    标签: ruby-on-rails minitest


    【解决方案1】:

    实例变量不是全局变量。它们是作用域为定义 的实例的词法变量。如果您在没有先学习 Ruby 的情况下从 Rails 开始,这是一个常见的初学者挂断,因为它“神奇地”使您的控制器实例变量可用于视图。

    您认为您在控制器中定义的实例变量应该在测试中设置的期望是完全错误的,因为它们是不同类的完全独立的实例。

    在旧版控制器测试中,assigns 方法通常用于插入控制器内部并编写有关其实例变量的断言:

    assert(assigns(:cu_buyer))
    

    这已被弃用并完全从 Rails 中删除,但仍然是 exists as an gem。不建议在遗留代码之外使用它。相反,现代方法是编写 test the response and effects of your controller without poking into its internals 的集成测试。

    【讨论】:

    • 非常有帮助的解释。虽然我了解更改的原因,并且在大多数情况下测试视图会影响该测试,但此特定方法是重构并分配给 application_controller。那么,为了测试这种重构,对 gem 有什么更好的解决方案:拥有/创建一个视图,这个实例变量是可用的?
    • 我真的不知道,因为我不知道这应该测试什么行为,或者“测试视图将影响该测试”甚至应该是什么意思。您通过驱动整个堆栈的集成或系统测试来测试控制器,然后编写有关结果的断言——这就是现代方式。可以通过视图测试单独测试视图,但它们不经常使用,因为您可以通过系统测试覆盖整个应用程序的关键路径。
    猜你喜欢
    • 2011-12-12
    • 1970-01-01
    • 2014-10-06
    • 2022-06-21
    • 2017-06-18
    • 2017-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多