rspec 是否会记住“主题”块?

use*_*255 4 rspec subject behaviorsubject

我正在使用的编码标准指定一组测试函数的规范应该有一个主题,即被调用的函数。它看起来像这样:

define User do
  context :foo do
    let(:user) { FactoryGirl.create(:user) }
    subject { user.foo }
    it { ... }
  end
end
Run Code Online (Sandbox Code Playgroud)

subject块的典型用途是实例化您正在测试的类:

define User do
  subject { FactoryGirl.create(:user) }
  it { ... }
end
Run Code Online (Sandbox Code Playgroud)

我们的风格指南的预期效果是我们为每个正在测试的方法有一个不同的主题块。这会减慢我们的测试速度吗?如果我们subject以典型的方式使用,我们是否会从每个类只有一个主题块的内置记忆或其他加速中受益?

旁白:

我遇到过一种我们的风格不起作用的情况。使用时any_instance.should_receive您不能遵循我们的风格指南,否则规范将始终失败。相反,您需要使用更传统的方法subject,您正在测试的对象在哪里,并在您的规范中调用它的方法。

# passing spec
define Foo do
  before { Bar.any_instance.stub(:baz) }
  subject { FactoryGirl.create(:foo) }
  it "bazzes Bars" do
    Bar.any_instance.should_receive(:baz)
    subject.baz_the_bars
  end
end

# spec follows style guide but fails
define Foo do
  before { Bar.any_instance.stub(:baz) }
  let(:foo) { FactoryGirl.create(:foo) }
  subject { foo.baz_the_bars }

  it "bazzes Bars" do
    Bar.any_instance.should_receive(:baz)
    subject
  end
end

class Foo
  has_many :bars

  def baz_the_bars
    bars.collect do |bar|
      bar.baz
    end.count(true)
  end
end
Run Code Online (Sandbox Code Playgroud)

我应该注意这种风格的其他问题吗?

She*_*ter 5

subject是懒惰地创建,每次测试,并限定为context/ describe,就像let. 他们不应该有任何额外的开销。

我个人不喜欢你展示的风格,但是当我有从方法返回的非常复杂(或只是大)数据对象时,我做了类似的事情。

describe "A thing" do
  subject(:foo) { FactoryGirl.create(:foo) }

  # A very complicated object from this method
  describe "the result of calling frob" do
    subject(:result) { foo.frob }

    it { should be_active }
    it { should be_alive }
  end
end
Run Code Online (Sandbox Code Playgroud)