'受让人'在rspec水豚中找不到的方法

时间:2018-06-07 14:19:55

标签: ruby-on-rails rspec capybara

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

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方法吗?

2 个答案:

答案 0 :(得分:2)

assigns仅在控制器测试中可用 - 它在Rails 5中被折旧。

  

测试控制器设置的实例变量是不好的   理念。这大大超越了测试的界限   应该知道。您可以测试设置的cookie,HTTP代码   返回,视图如何显示,或DB发生了什么突变,   但是测试控制器的内部结构并不是一个好主意    - David Heinemeier Hansson

在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这样的Rack中间件(由Devise使用)或会话必须存根。

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

  

功能规格是用于执行切片的高级测试   通过应用程序的功能。他们应该开车   应用程序只能通过其外部界面,通常是网页   https://relishapp.com/rspec/rspec-rails/v/3-7/docs/feature-specs

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

  

请求规范为Rails&#39;提供了一个薄的包装器。集成测试,   并设计为通过完整堆栈驱动行为,包括   路由(由Rails提供)并且没有存根(由您决定)   https://relishapp.com/rspec/rspec-rails/v/3-7/docs/request-specs/request-spec

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

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

请参阅:

答案 1 :(得分:1)

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