简体   繁体   English

如何为通过 Rubocop 标准的 Rails 视图编写 RSpec?

[英]How do I write an RSpec for a Rails view that passes Rubocop's criteria?

I used rails generate scaffold to generate my controller, model, views, etc. as well as their associated rspecs.我使用rails generate scaffold来生成我的 controller、model、视图等以及它们相关的 rspec。 The rspec generated for the views all have a common problem. rspec生成的views都有一个通病。 The generated rspec is:生成的rspec为:

require 'rails_helper'

RSpec.describe 'import_files/new', type: :view do
  before do
    assign(:import_file, build(:import_file))
  end

  it 'renders new import_file form' do
    render

    assert_select 'form[action=?][method=?]', import_files_path, 'post' do
      assert_select 'input[name=?]', 'import_file[path]'
      assert_select 'select[name=?]', 'import_file[file_type]'
    end
  end
end

Rubocop is complaining that there is no expectation within the example (with the error at the line with it ). Rubocop 抱怨示例中没有期望(错误在it行)。 The assert_select from what I can tell does an expectation as well as other things so I tried adding this to my .rubocop.yml file:据我所知, assert_select做了一个期望以及其他事情,所以我尝试将它添加到我的.rubocop.yml文件中:

RSpec:
  Language:
    Expectations:
      - assert_select

but now Rubocop complains that the example has three expectations instead of just one.但是现在 Rubocop 抱怨这个例子有三个期望而不是只有一个。 Curiously, in the RSpec Style Guide example of a view spec , they have the same basic structure of an expect selecting out a piece of the DOM and passing it down to an inner expect -- AND, Rubocop flags it as having too many expectations.奇怪的是,在视图规范的 RSpec 样式指南示例中,它们具有相同的基本结构,即期望选择 DOM 的一部分并将其传递给内部期望——并且,Rubocop 将其标记为具有太多期望。

Perhaps RSpec/MultipleExpectations in views should just always be disabled?也许视图中的RSpec/MultipleExpectations应该始终被禁用?

Edit (and a somewhat different question):编辑(和一个有点不同的问题):

After the render what can I use to select out just the form and it's children without adding in any expectations?render之后,我可以使用什么来 select 只是形式和它的孩子而不添加任何期望?

I'm thinking (roughly sketching and not knowing what I'm doing) something like:我在想(粗略地画出草图,不知道自己在做什么)是这样的:

RSpec.describe 'import_files/new', type: :view do
  before do
    assign(:import_file, build(:import_file))
  end

  it 'renders new import_file form' do
    render

    expect(rendered).to have_selector('form', method: :post, action: import_files_path)
  end

  it 'renders new import_file form witn path field' do
    render

    select_out_just_the_form do
      assert_select 'input[name=?]', 'import_file[path]'
    end
  end

  it 'renders new import_file form with file_type field' do
    render

    select_out_just_the_form do
      assert_select 'select[name=?]', 'import_file[file_type]'
    end
  end
end

Two questions now:现在有两个问题:

  1. what can I use for the select_out_just_the_form ?我可以为select_out_just_the_form使用什么?
  2. Could I / should I rearrange this so the render happens just once something like this:我可以/我应该重新安排它以便渲染只发生一次,如下所示:
RSpec.describe 'import_files/new', type: :view do
  before do
    assign(:import_file, build(:import_file))
  end

  begin
    render

    it 'renders new import_file form' do
      expect(rendered).to have_selector('form', method: :post, action: import_files_path)
    end

    select_out_just_the_form do
      it 'renders new import_file form witn path field' do
        assert_select 'input[name=?]', 'import_file[path]'
      end

      it 'renders new import_file form with file_type field' do
        assert_select 'select[name=?]', 'import_file[file_type]'
      end
    end
  end
end

The reason the 2nd style might be bad is if the outer form fails, there are going to be 3 errors where actually the inner 2 errors are a simple consequence of the outer error of not rendering the form.第二种样式可能不好的原因是,如果外部表单失败,将出现 3 个错误,其中实际上内部 2 个错误是外部错误未呈现表单的简单结果。 I remember when a simple omitted semicolon could generate loads of errors which only created a big mess.我记得当一个简单的省略分号会产生大量错误而只会造成大混乱。

This is what I came up with.这就是我想出的。

require 'rails_helper'

RSpec.describe 'import_files/new', type: :view do
  let(:form_css) { "form[action='#{import_files_path}'][method=post]" }

  before do
    assign(:import_file, build(:import_file))
    render
  end

  it 'renders new import_file form' do
    assert_select form_css
  end

  describe 'the rendered form' do
    let(:form) do
      css_select form_css
    end

    it 'has a path field' do
      assert_select form, 'input[name=?]', 'import_file[path]'
    end

    it 'has a file_type field' do
      assert_select form, 'select[name=?]', 'import_file[file_type]'
    end
  end
end

Execution results:执行结果:

import_files/new
  renders new import_file form
  the rendered form
    has a path field
    has a file_type field

Finished in 0.25221 seconds (files took 1.35 seconds to load)
3 examples, 0 failures

I also added this to my.rubocop.yml (as previously stated):我还将此添加到 my.rubocop.yml(如前所述):

RSpec:
  Language:
    Expectations:
      - assert_select

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM