【问题标题】:How to avoid Rspec shared examples 'previously defined' warning?如何避免 Rspec 共享示例“先前定义”警告?
【发布时间】:2015-07-03 14:42:59
【问题描述】:

我正在尝试学习如何使用 Rspec 的共享示例功能,并在运行测试时收到警告:

WARNING: Shared example group 'required attributes' has been previously defined at:
  /Users/me/app/spec/support/shared_examples/required_attributes_spec.rb:1
...and you are now defining it at:
  /Users/me/app/spec/support/shared_examples/required_attributes_spec.rb:1
The new definition will overwrite the original one.
....

我已阅读我认为是关于此问题的文档here,但我无法理解它/看到我的案例的要点。

这是我分享的例子:

# spec/support/shared_examples/required_attributes_spec.rb

shared_examples_for 'required attributes' do |arr|
  arr.each do |meth|
    it "is invalid without #{meth}" do
      subject.send("#{meth}=", nil)
      subject.valid?
      expect(subject.errors[meth]).to eq(["can't be blank"])
    end
  end
end

我试图在User 模型和Company 模型中使用它。这是它的样子:

# spec/models/user_spec.rb

require 'rails_helper'

describe User do
  subject { build(:user) }
  include_examples 'required attributes', [:name]
end

# spec/models/company_spec.rb

require 'rails_helper'

describe Company do
  subject { build(:company) }
  include_examples 'required attributes', [:logo]
end

根据我在上面链接的 Rspec 文档中的建议,我尝试将 include_examples 更改为 it_behaves_like,但这并没有帮助。我还完全注释掉了company_spec.rb,所以只有一个使用共享示例的规范,我仍然收到警告。

谁能帮我看看这里到底发生了什么以及在这种情况下我应该怎么做才能避免警告?

【问题讨论】:

    标签: ruby-on-rails ruby testing rspec warnings


    【解决方案1】:

    我在 Rspec Github 的 issue 中找到了答案:

    以防万一有人用谷歌搜索并登陆这里。如果将您的文件与 共享示例到支持文件夹未修复以下问题 错误...确保您的文件名不以_spec.rb.结尾

    【讨论】:

      【解决方案2】:

      作为对此的跟进,我在包含的共享上下文中遇到了问题,该问题的文件名_spec.rb 结尾,并且是通过require_relative 手动加载的,而不是自动加载的。就我而言,问题是复制粘贴问题。测试看起来像这样:

      RSpec.shared_examples 'foo' do
        RSpec.shared_examples 'bar' do
          it ... do... end
          it ... do... end
          # etc.
        end
      
        context 'first "foo" scenario' do
          let ...
          include_examples 'bar'
        end
      
        context 'second "foo" scenario' do
          let ...
          include_examples 'bar'
        end
      end
      

      目的是提供一组共享的示例,这些示例执行多个操作上下文以获得良好的覆盖率,所有示例都通过该内部共享示例列表运行。

      这个错误很简单但很微妙。由于我关闭了 RSpec 猴子补丁 (disable_monkey_patching!),因此我必须在顶层使用 RSpec.<foo>。但是在任何其他 RSpec 块中,使用 RSpec.<foo> 定义了 RSpec 的顶级 :main 上下文中的实体。因此,第二组共享的“内部”示例没有在 'foo' 中定义,它们是在顶层定义的。这足以使事情变得混乱,足以触发 RSpec 警告,而不是一个其他文件 require_relative'd 上面的代码。

      解决方法是只在嵌套集中执行 shared_examples 'bar',而不是 RSpec.shared_examples 'bar',以便在内部上下文中正确描述内部示例。

      (旁白:这是一个有趣的例子,说明关闭猴子补丁比乍一看更重要 - 这不仅仅是为了命名空间的纯度。它允许在声明中更清晰地区分“这是顶层”和“这是嵌套的”。)

      【讨论】:

      • 用 shared_examples 替换 RSpec.shared_examples 对我有用,而重命名文件没有
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-25
      • 2021-02-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多