【问题标题】:'assigns' method not found in rspec capybara在 rspec capybara 中找不到“分配”方法
【发布时间】:2018-06-07 14:19:55
【问题描述】:

我的控制器中有以下代码:

private
def remaining_words
    @remaining_words = Vocab.all.where.not(id: session[:vocab_already_asked])
    @questions_remaining = @remaining_words.length - 4
    @quiz_words = @remaining_words.shuffle.take(4)

这是我的测试:

feature 'Quiz functionality'   do
  scenario "gets 100% questions right in quiz" do
    visit(root_path)
    visit(start_quiz_path)

    assigns(:questions_remaining).length.to_i.times do
      orig_value = find('#orig', visible: false).value
      choose(option: orig_value)
      click_on('Submit')
      expect(page).to have_content('You got it right!')
      expect(page).not_to have_content('Sorry, wrong answer!')
    end

    expect(page).to have_content("Your score is 27/27")
    save_and_open_page
  end
end

我在运行测试时收到错误消息:

NoMethodError: undefined method `assigns' for #<RSpec::ExampleGroups::QuizFunctionality:0x007f8f2de3f2b0>
     # ./spec/features/quizzes_spec.rb:9:in `block (2 levels) in <top (required)>'

我也尝试过使用 controller.instance_variable_get(:remaining_words) 并收到此错误消息

NameError:
       undefined local variable or method `controller' for #<RSpec::ExampleGroups::QuizFunctionality:0x007fc4b99251a0>

我在设置测试时是否遗漏了什么?我应该使用 describe 而不是 feature 来启用 assign 方法吗?

【问题讨论】:

    标签: ruby-on-rails rspec capybara


    【解决方案1】:

    assigns 仅在控制器测试中可用 - 它在 Rails 5 中已被贬值。

    测试控制器设置了哪些实例变量是不好的 主意。这严重超出了测试的界限 应该知道。你可以测试设置了什么cookies,什么HTTP代码 返回,视图的外观,或者数据库发生了什么变化, 但是测试控制器的内部并不是一个好主意。
    - 大卫·海涅迈尔·汉森

    在 RSpec 控制器规范中包含已弃用的 ActionController::TestCase

    控制器规范通过 type: :controller 元数据来标识。

    RSpec.describe ThingsController, type: :controller do
      # ...
      describe "GET #index" do
      end
    end
    

    如果您在config.infer_spec_type_from_file_location! 中设置了config.infer_spec_type_from_file_location!,RSpec 将推断spec/controllers 中的任何规范都有type: :controller

    您应该避免新应用程序的控制器规范,而是支持请求和功能规范。除了违反封装之外,控制器规范的主要问题之一是整个请求阶段都被存根,请求实际上并没有通过机架或可以掩盖路由错误的路由,这意味着像 Warden 这样的机架中间件(由 Devise 使用)或者会话必须被存根。

    如果您有旧版应用程序,您可以使用gem 重新引入assigns。如果你只是学习 RSpec,你应该选择更多最新的教程。

    功能规格是高级测试,旨在执行 通过应用程序实现功能。他们应该驾驶 应用程序只能通过其外部接口,通常是网页。
    https://relishapp.com/rspec/rspec-rails/v/3-7/docs/feature-specs

    使用功能规范进行以用户故事为中心的高级测试。使用RSpec.feature "New Cool Feature" 编写功能规范。

    请求规范为 Rails 的集成测试提供了一个精简的包装, 并旨在通过整个堆栈驱动行为,包括 路由(由 Rails 提供)并且没有存根(这取决于您)。
    https://relishapp.com/rspec/rspec-rails/v/3-7/docs/request-specs/request-spec

    使用RSpec.describe "Some resource", type: :request 编写功能规范。

    请求规范对于测试 API 或当您只需要快速测试以确保数据库发生正确的突变或发送正确的 http 响应时非常宝贵。

    见:

    【讨论】:

    • RSpec 仍然生成控制器规范的事实只是 rspec-rails 落后于最先进技术的问题。
    【解决方案2】:

    您正在编写无法访问控制器/控制器实例变量的功能规范/集成测试。它们更像是从用户角度执行的黑盒测试。在为测试设置数据时,您应该知道需要问多少问题,然后在测试中对其进行硬编码,或者更好的是,根据页面内容检测是否有更多问题需要回答(就像用户必须)。

    【讨论】:

    • 我明白了。问题的数量目前是硬编码的,我认为应该动态检测它以使其更健壮。那我就把它硬编码了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 2018-08-20
    • 1970-01-01
    相关资源
    最近更新 更多