RSpec测试:让Vs。 之前

在RSpec中,有两种不同的编写DRY测试的方法,即使用beforelet 。 它们的目的是创建在测试之间通用的变量。 在本文中,我们将探讨before和let之间的区别,并解释为什么Ruby社区更喜欢let

让我们创建延迟评估的局部变量。 这意味着在首次运行let()定义的方法之前,不会对其进行评估。 它使规范变干并使其更具可读性。

$count = 0
describe "let" do
  let( :count ) { $count += 1 }
  it "stores the value" do
    expect(count).to eq( 1 )
    expect(count).to eq( 1 )
  end
  it "is not cached across examples" do
    expect(count).to eq( 2 )
  end
end

let不应用于必须保存到数据库的局部变量,因为除非已被引用,否则它们不会保存到数据库。 在这种情况下,您应该使用let!在块之前

我们正在创建的测试是使用RSpec和Capybara完成的

另外, 永远不要在块之前的一个let块之内,这就是let! 是为!

让!

与let不同,您可以使用let! 强制在每个示例之前调用方法 。 这意味着,即使您没有在示例中调用辅助方法,该方法也将在示例运行之前被调用。

$count = 0
describe "let!" do
  invocation_order = []
  let!( :count ) do
    invocation_order << :let!
    $count += 1
  end
  it "calls the helper method in a before hook" do
    invocation_order << :example
    expect(invocation_order).to eq([ :let! , :example ])
    expect(count).to eq( 1 )
  end
end

与let块一样,如果有多个let! 块以相同的名称定义,将执行最新的块。 核心区别在于让! 如果这样使用,则将执行多次,而let块将仅执行最后一次。

之前(:每个)

即使示例未使用该块中定义的任何实例变量,before(:each)块也将在每个示例之前运行。 这会明显减慢实例变量的设置。

class User
  def tests
    @tests || = []
  end
end
describe User do
  before( :each ) do
    @user = User.new
  end
  describe "initialized in before(:each)" do
    it "has 0 tests" do
      @user.should have( 0 ).tests
    end
    it "can accept new tests" do
      @user.tests << Object.new
    end
    it "does not share state across examples" do
      @user.should have( 0 ).tests
    end
  end
end

在几乎每种情况下,最好在块之前使用let。 根据您的个人喜好,您可以在以下情况下在块之前使用:

  • 有一定数量的变量。
  • 有些变量不需要直接引用而是必需的。
  • 有许多命令要执行,因为当涉及到许多命令时,其语法更加清晰。
  • 创建模拟/存根。

尝试一下,创建自己的模型或控制器测试

之前(:全部)

在组中的所有示例之前,该块仅执行一次。 在某些情况下,这会减少执行力和工作量。

class User
  def tests
    @tests || = []
  end
end
describe User do
  before( :all ) do
    @user = User.new
  end
  describe "initialized in before(:all)" do
    it "has 0 tests" do
      @user.should have( 0 ).tests
    end
    it "can get accept new tests" do
      @user.tests << Object.new
    end
    it "shares state across examples" do
      @user.should have( 1 ).tests
    end
  end
end

除非您知道自己在做什么,否则在RSpec中使用before(:all)会给您带来很多麻烦! 它在事务之外运行,因此此处创建的数据将渗入其他规范。

结论

让块为表带来比之前更多的信息。 这完全取决于您需要什么以及如何使RSpec测试正常工作,或者考虑使用FactoryGirl创建数据。

除了速度较慢之外,before块的主要问题之一是拼写错误可能导致错误和误报,从而允许某些类型的测试在不应该通过的情况下通过。

before( :each ) do
    @user = User.find( username: "kolosek" )
    @user.logout
end
it "should log the user out" do
    expect(@usr).to be_nil
end

由于先前未定义@usr,因此测试将通过,默认情况下@usr为nil。 使用let的相同测试会引发NameError,因为未定义@usr。

希望这将帮助您更好地了解let和before块之间的区别。

感谢您的阅读!

先前发布在https://kolosek.com/rspec-let-vs-before/

From: https://hackernoon.com/rspec-testing-let-vs-before-s2q83y16

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值