将参数传递给rspec共享示例

Nth*_*oss 15 ruby rspec parameter-passing

我有一个进程返回一个结果集,我想使用rspec测试其有效性.该过程将根据参数返回不同的结果,但有许多示例对所有这些都是通用的,因此我想创建一组可以针对所有这些示例运行的常见示例.

我知道首选的做法是使用let来构建结果.问题是每个过程需要一两分钟来生成结果,我可能有30个例子.与所有基于不同的参数排列的我运行约500 examples.If我不得不重建的结果为每比如,试验将运行超过一天.

所以相反,我在before(:all)块中构建一个结果,并将它分配给这样的属性:

RSpec.describe 'Test Description' do
  attr_reader :result

  before(:all)
    @result = build_result({some_parameters})
  end

  context 'Some context' do
    it 'Looks lik a result' do 
      expect(result.something).to ...
    end

    it 'Feels lik a result' do 
      expect(result.something).to ...
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

也许有比使用属性更好的方法.我想做这样的事情:

RSpec.describe 'Test Description' do
  attr_reader :result

  before(:all)
    @result = build_result({some_parameters})
  end

  context 'Some context' do
    it_behaves_like "A result" result
  end
end
Run Code Online (Sandbox Code Playgroud)

在此上下文中使用属性失败.有没有不同的方法来做到这一点?

Rya*_*rtz 68

您可以将参数传递给共享示例,如下所示:

shared_examples_for "A result" do |argument|
 # some tests with argument
end
Run Code Online (Sandbox Code Playgroud)

然后my_argument像这样传递:

it_behaves_like "A result", my_argument
Run Code Online (Sandbox Code Playgroud)

  • 如果`my_argument`是用`let`定义的呢?不起作用. (8认同)
  • 那么这将是一种代码味道。特别是当共享示例块在不同的文件中定义时。共享函数不应隐式依赖于其语义可能因上下文而异的全局符号。 (5认同)
  • 和@gamliela一样的问题.用`let`定义的变量可以传递给shared_examples吗? (4认同)
  • @gamliela,如果将my_argument定义为let,则无需将其作为参数传递。您可以直接在`shared_examples`中直接使用它。 (3认同)
  • 这是您访问此页面时正在寻找的答案 (2认同)

Lau*_*nen 0

您可以将所有关于结果的断言分组到一个示例中。这样,let 只被评估一次。

RSpec.describe 'Test Description' do
  context 'for params x and y' do
    let(:expected_x) { 'x' }
    let(:expected_y) { 'y' }

    subject { build_result({x: 'x', y: 'y'}) }

    specify :aggregate_failures do
      expect(subject.x).to eq(expected_x)
      expect(subject.y).to eq(expected_y)
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

它确实违背了“一次测试,一次断言”的指导方针,但如果操作成本非常高,我认为这是一种合理的做法。对于:aggregate_failures每个断言,您都会遇到单独的失败,因此您不会错过这一点。