RSpec:let和a之前的区别是什么?
在RSpec中let
和a before
什么区别?
何时使用每个?
下面的例子中会有什么好办法(let or before)?
let(:user) { User.make !} let(:account) {user.account.make!} before(:each) do @user = User.make! @account = @user.account.make! end
我研究了这个stackoverflowpost
但是如何定义像上面这样的关联的东西呢?
人们似乎已经解释了一些不同的基本方法,但在(:全部)之前被排除在外,并没有解释为什么应该使用它们。
我相信实例variables在绝大多数规范中没有被使用,部分原因是由于这个答案中提到的原因,所以在这里我不会提到它们作为一个选项。
让块
let
块中的代码只在引用时执行,延迟加载意味着这些块的sorting是不相关的。 这给你一个大量的权力,减less重复设置通过您的规格。
一个(非常人为的,小的)例子是:
let(:person) { build(:person) } subject(:result) { Library.calculate_awesome(person, has_moustache) } context 'with a moustache' do let(:has_moustache) { true } its(:awesome?) { should be_true } end context 'without a moustache' do let(:has_moustache) { false } its(:awesome?) { should be_false } end
你可以看到has_moustache
在每种情况下的定义都是不同的,但是不需要重复subject
定义。 需要注意的是,将使用在当前上下文中定义的最后的let
块。 这对于设置大部分规格的默认设置是很好的,如果需要的话可以覆盖。
例如,检查calculate_awesome
的返回值,如果传递一个top_hat
设置为true但没有胡须的person
模型,将会是:
context 'without a moustache but with a top hat' do let(:has_moustache) { false } let(:person) { build(:person, top_hat: true) } its(:awesome?) { should be_true } end
另一个要注意的关于让块,他们不应该使用,如果你正在search的东西已被保存到数据库(即Library.find_awesome_people(search_criteria)
),因为他们不会被保存到数据库,除非他们已经引用。 let!
或before
块应该在这里使用。
另外, 以前从来没有用过触发执行let
块,这就是let!
是为了!
让! 块
let!
块按照它们定义的顺序执行(非常类似于之前的块)。 与之前的块之间的一个核心区别是你得到了对这个variables的明确引用,而不需要回退到实例variables。
如同let
块,如果多重let!
块被定义为相同的名称,最近的是将在执行中使用。 核心的区别是let!
如果像这样使用块,将会执行多次,而let
块只会执行最后一次。
之前(:每个)块
before(:each)
是块之前的默认值,因此可以像before {}
引用before {}
而不是before(:each) {}
指定完整的before(:each) {}
。
在一些核心情况下使用块before
我个人偏好。 如果出现以下情况,我将在使用前
- 我正在使用嘲弄,残片或双打
- 有任何合理的大小设置(通常这是你的工厂特征没有正确设置的标志)
- 有许多variables我不需要直接引用,但是需要进行设置
- 我在rails中编写function控制器testing,我想执行一个特定的请求来testing(即
before { get :index }
)。 尽pipe在很多情况下你可以使用这个subject
,但是如果你不需要参考的话,它有时会更加明确。
如果你发现你自己的规格before
块before
写得很大,请检查你的工厂,确保你完全了解特性和灵活性。
之前(:全部)块
这些只在当前语境(及其子语)的规范之前执行过一次。 如果写得正确的话,这些可以被用来取得巨大的优势,因为在某些情况下这可以减less执行和努力。
一个例子(几乎不影响执行时间)嘲笑一个testing的ENVvariables,你应该只需要做一次。
希望帮助:)
几乎总是,我更喜欢let
。 你链接的post指出let
也更快。 但是,有时候需要执行很多命令时,我可以使用before(:each)
因为当涉及到很多命令时,它的语法更加清晰。
在你的例子中,我肯定会喜欢使用let
而不是before(:each)
。 一般来说,当只做一些variables初始化时,我倾向于使用let
。
没有提到的一个很大的区别是用let
定义的variables在第一次调用之前不会被实例化。 因此,虽然before(:each)
块会实例化所有variables,但let
我们来定义可能在多个testing中使用的许多variables,但不会自动实例化它们。 如果不知道这一点,如果您预期所有的数据都会被预先加载,您的testing可能会回来咬你自己。 在某些情况下,甚至可能需要定义一些let
variables,然后使用before(:each)
块来调用每个let
实例,以确保数据可用于开始。
看起来你正在使用机械师。 当心,你可能会看到一些问题,使! (非爆炸版本)发生在全局夹具事务之外(如果您也使用事务性夹具),则会损坏您的其他testing的数据。
- Shoulda / RSpec匹配器 – 条件validation
- 如何在Rails应用程序中testingElasticSearch(Rspec)
- 如何设置方法testing中使用的私有实例variables?
- 之前所有vs之前的轨道rspec
- 运行规范时禁止Ruby警告
- 未定义的方法`得到'为#<RSpec :: Core :: ExampleGroup :: Nested_1:0x00000106db51f8>
- 尝试运行rspec时出错:`require':无法加载这样的文件 – rails_helper(LoadError)
- 在大型Rails应用程序中加速RSpectesting
- rspec 3 – 存根类方法