【问题标题】:Using a Helpers module to declare contexts in Rspec使用 Helpers 模块在 Rspec 中声明上下文
【发布时间】:2018-08-30 01:42:00
【问题描述】:

我正在尝试从 Helpers 模块中递归声明 Rspec 中的上下文。

(我的代码将以一种不寻常的方式使用这些上下文,即递归地对嵌套哈希中的键进行断言。也许我可以用不同的方式解决这个问题,但这不是重点。)

一个最小的完整示例是:

module Helpers
  def context_bar
    context "bar" do
      it "baz" do
        expect(true).to be true
      end
    end
  end
end

include Helpers

describe "foo" do
  Helpers.context_bar
end

如果我现在在 Rspec 中执行此代码,它会失败:

RuntimeError:
  Creating an isolated context from within a context is not allowed. Change `RSpec.context` to `context` or move this to a top-level scope.

然后我可以这样重构它:

def context_bar
  context "bar" do
    it "baz" do
      expect(true).to be true
    end
  end
end

describe "foo" do
  context_bar
end

这对我来说很好用,尽管我失去了在模块名称空间中使用此方法和类似方法所带来的可读性优势。

我有什么办法可以完成这项工作吗?

(请注意,这个问题与 this 或 Rspec 文档中的 here 等其他问题有表面上的相似性。这似乎使 Helpers 在示例中可用,但它不允许我实际声明上下文。)

【问题讨论】:

  • 您提供的示例可能会通过共享示例更好地解决:relishapp.com/rspec/rspec-core/v/3-7/docs/example-groups/…您有理由不使用它吗?
  • 没有理由,如果可以这样做的话。
  • 好的,我认为这可能是一种智力挑战;)在这种情况下——共享示例是可行的方法——它们完全是一种提取可重复上下文和示例的方法。
  • 谢谢,那我去看看。
  • 其实不行。然后我遇到:can't include shared examples recursively.

标签: ruby rspec


【解决方案1】:

正如 cmets 中所建议的,这里的答案通常是使用共享示例。因此,我可以将此代码示例重构为:

RSpec.shared_examples "context_bar" do
  context "bar" do
    it "baz" do
      expect(true).to be true
    end
  end
end

describe "foo" do
  include_examples "context_bar"
end

但是,如果我声明一个 recursive “函数”,例如:

RSpec.shared_examples "compare" do |ref1, ref2|
  ...
end

并使用以下方法调用它:

include_examples "compare", ref1, ref2

这失败了:

ArgumentError:
  can't include shared examples recursively

另请参阅docs 中的共享示例。

cmets 中还建议我可以使用自定义匹配器。确实,有人做了非常相似的事情here

【讨论】:

    【解决方案2】:

    您可以在配置中添加上下文。 rspec-graphql_response gem 做得很好here。虽然这是否是一个好主意是另一个问题。

    基本上是这样的:

    
    require 'spec_helper'
    
    # Put this in a helper somewhere.
    RSpec.configure do |config|
      def my_context_helper(&block)
        block.call if block_given?
      end
    end
    
    RSpec.describe 'Smoke Test' do
      my_context_helper
    
      my_context_helper do
        # do something
      end
    end
    
    

    您可以使用实例变量传递上下文。我认为您需要小心碰撞并正确拆除您的规格。否则,您可能会在测试中得到意想不到的结果。共享示例或共享上下文可能更安全、更容易,并且可以按预期使用 RSpec DSL。

    我也做了一个秒杀here

    【讨论】:

      猜你喜欢
      • 2023-03-17
      • 2014-08-07
      • 2018-06-25
      • 1970-01-01
      • 1970-01-01
      • 2019-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多