rspec`his`语法与动态条件

问题描述 投票:20回答:3

我一直非常喜欢使用contextssubjectsits和rspec来真正清理我的测试代码。典型例子:

context "as a user" do
  subject{ Factory :user }

  its(:name){ should == "Bob" }
end

我无法弄清楚的是我如何使这个条件动态(即基于其他对象)。 its似乎实例化了该块中的属性,因此我无法访问它周围的所有内容。我喜欢做类似的事情:

its(:name){ should == subject.contact.name }

但我看不出任何实现这一目标的方法。有没有人知道是否有一个方法代理到这个实例eval,它提供了对原始对象的访问?或者,如果有任何其他方式,我可以使用我正在检查的属性实例范围之外的方法?

additional info

似乎subject块中的its变为实际属性(在这种情况下为name

有趣的是,我可以访问我的任何let方法,但同样,我无法访问我的原始subject有问题。

ruby scope rspec2
3个回答
29
投票

您几乎在回答自己,在设置主题之前使用let分配。然后你可以随处参考:

context "as a user" do
  let(:user) { Factory(:user) }
  subject { user }
  its(:name) { should == user.contact.name }
end

我也是contextsubjectits爱好者!


1
投票

不确定是否有办法完全按照你的要求去做,因为块内的“主题”成为User#name的返回值。

相反,我使用let方法以及以下规范样式来编写这种测试:

describe User do

  describe '#name' do
    let(:contact) { Factory(:contact, name: 'Bob') }
    let(:user) { Factory(:user, contact: contact) }

    subject { user.name }

    it { should == 'Bob' }
  end

end

这当然会对您的联系人所代表的内容做出一些假设(这里是一个关联或类似的)。您也可以选择存储User#contact的返回值,而不是依靠FactoryGirl来建立“真实”关联。

无论您在这些方面做出何种选择,这一策略对我来说都很有效。我发现它允许我更简洁地了解正在测试的内容,同时保留关于预期返回值来自何处的信息(针对其他开发者和未来的自我)。


-5
投票

您可以在主题块中设置实例变量:

context 'as a user' do
  subject { @user = FactoryGirl.create(:user) }

  its(:name) { should == @user.name }
end
© www.soinside.com 2019 - 2024. All rights reserved.