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