在 RSpec 测试中“let”真正节省了多少时间?

2024-01-01

我发现在代码中设置变量比使用变量容易得多let. let很挑剔,总是告诉我错误使用的方式。

当我在规范中使用简单的变量声明时,例如

tx_good = makeTransaction1(),一切正常。

但是当我使用let像这样

let(:tx_good) { makeTransaction1() }我总是会收到一些错误,比如这样告诉我它不能去这里或那里......

  `let` and `subject` declarations are not intended to be called
   in a `before(:context)` hook, as they exist to define state that
   is reset between each example, while `before(:context)` exists to
   define state that is shared across examples in an example group.

考虑到使用的挑剔程度let是,我不得不想知道是否值得我必须付出额外的努力和关心来使用它。有谁知道使用 let 与仅仅预先分配一个变量相比,真正节省了多少处理时间?

我想遵循良好的测试协议,所以我希望有人能够说服我为什么应该使用let就像(看起来)其他人一样。


你用错了这些东西,我理解你的沮丧。所以让我给你一份简明的使用手册letRSpec 中的 s。

主要使用价值let并非来自节省的处理能力。它是更广泛的 RSpec 理念不可或缺的一部分。我会尽力解释,希望你会更容易进步......

let is lazy

当且仅当它在规范中实际使用时,您在块内定义的任何内容都会被调用:

context do
  let(:foo) { sleep(10000) } # will not happen
  specify { expect(1).to eq(1) }
end 

context do 
  specify do 
     foo = sleep(10000) # you'll wait
     expect(1).to eq(1)
  end
end

Use let!,这是急切的(即不是懒惰的)版本let

let已被记忆

块内定义的任何内容都只会发生一次(在上下文范围内):

context do
  let(:random_number) { rand }
  specify do
    expect(random_number).to eq(random_number) # will always pass
  end
end

如果您不需要此功能,请定义一个方法:

context do
  def random_number
    rand
  end
  specify do
    expect(random_number).to eq(random_number) # sometimes pass, mostly fail
  end
end

let在较低级别的上下文中覆盖let更高层次的定义:

context do
   let(:x) { 1 }
   specify { expect(x).to eq(1) # pass

   context 'with different x' do 
     let(:x) { 2 }
     specify { expect(x).to eq(2) # pass
   end

   context do
     specify { expect(x).to eq(1) # pass
   end
end

^ 这允许您以某种方式编写规范,其中仅在上下文中提到设置的相关“部分”,例如:

context do 
   let(:x) { 1 }
   let(:y) { 1 }
   let(:z) { 1 }
   specify { expect(foo(x, y, z)).to eq(3) }

   context 'when z is nil'
     let(:z) { nil }
     specify { expect(foo(x, y, z)).to raise_error) } # foo doesn't work with z = nil
   end

   context 'when x is nil'
     let(:x) { nil }
     specify { expect(foo(x, y, z)).to eq(15) } 
   end
end

Bonus: subject是一个魔法let

# writing 
subject { foo(x) }
# is almost the same as writing 
let(:subject) { foo(x) }

subject是 RSpec 中的保留概念,它是“您测试的东西”,因此您可以使用 `foo(x, y, z) 编写示例,如下所示:

context do 
   let(:x) { 1 }
   let(:y) { 1 }
   let(:z) { 1 }
   subject { foo(x, y, z) }
   specify { expect(subject).to eq(3) }

   context 'when z is nil'
     let(:z) { nil }
     specify { expect(subject).to raise_error) } # foo doesn't work with z = nil
   end

   context 'when x is nil'
     let(:x) { nil }
     specify { expect(foo(subject)).to eq(15) } 
   end
end

关于您遇到的错误...

let and subject声明不打算被调用 Abefore(:context)钩子,因为它们的存在是为了定义状态 在每个示例之间重置,同时before(:context)存在于
定义在示例组中的示例之间共享的状态。

你正在做类似的事情

before do
  let(:x) { ... }
end

只是不这样做,你定义let inside describe and context,但您可以在内部使用它们(不是定义它们,而是使用定义的内容)before and specify:

let(:name) { 'Frank' }
before do
  User.create name: name
end

specify do
   expect(User.where(name: name).count).to eq(1)
end
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 RSpec 测试中“let”真正节省了多少时间? 的相关文章

  • rspec 不适用于设计用户身份验证

    我正在尝试使用 RSpec 来测试我的 Rails 应用程序 该应用程序使用设计用户身份验证 gem 以下是已捆绑的相关 gem 的列表 devise 3 4 1 rails 4 1 7 4 1 6 rspec 3 1 0 rspec co
  • 黄瓜和 Rspec

    任何人都可以向我推荐黄瓜和 rspec 教程 rails 3 的好来源 简单示例 吗 Edit 实际上我正在寻找带有很好示例的免费在线资源 我觉得R规格书 http www pragprog com titles achbd the rsp
  • Ruby 元编程,RSpec 的“应该”如何工作?

    我正在阅读 RSpec 并试图弄清楚 RSpec 的 应该 是如何实现的 有人可以帮忙解释一下这个函数的元性质是如何工作的吗 代码位于此处 http github com dchelimsky rspec blob master lib s
  • RSpec 抛出分段错误

    有时我的测试套件会无缘无故地抛出分段错误 这是输出 Users Test rvm gems ruby 1 9 3 p392 gems activerecord 3 2 9 lib active record relation query m
  • Rails 模型测试 - 模拟与工厂

    Rails 测试模拟对象与使用工厂对象的最佳实践是什么 应该嘲笑only当模型可能转到外部源时使用 或者 您是否仅在测试实际模型并使用模拟来处理其他所有内容时才使用工厂 例如 如果我们有一个包含客户和订单的销售系统 那么当我们测试客户模型时
  • 访问网络编码性能测试的响应

    WebTestRequest request1 new WebTestRequest this Context Environment ToString IBWeb DefaultSB aspx request1 Headers Add n
  • 抑制 Rspec 3 的回溯

    我正在使用 rspec 3 2 0 和 capybara 2 4 4 并在我的 spec helper rb 文件中如下所示 config full backtrace false 对于大多数错误 我都会得到回溯 例如 Failure Er
  • Clojure:让作用域和函数返回值

    我在弄清楚如何使用 let 形式时遇到了一些麻烦 在下面的示例中 我想在本地绑定值 cols 以便稍后在函数中处理它 然而 我注意到 如果我使用 let 函数 sel opt tmp 将返回 nil 值而不是列表 defn sel opt
  • XPath JMeter 断言:错误“前缀必须解析为命名空间”

    我正在尝试使用JMeter XPath 断言 https jmeter apache org usermanual component reference html XPath Assertion使用 XPath 断言命令对标签值进行如下操
  • factory_girl + rspec 似乎并没有在每个示例后回滚更改

    类似于这里描述的问题 http rpheath com posts 411 how to use factory girl with rspec http rpheath com posts 411 how to use factory g
  • Rspec : PG::ConnectionBad: PQsocket() 无法获取套接字描述符

    我运行了 rspec 大部分测试都失败了 我对他们遇到了同样的错误 即 Failure Error Unable to find matching line from backtrace ActiveRecord StatementInva
  • 如何清除 ruby​​ 中 rspec 测试之间的类变量

    我有以下课程 我想确保类 url 只为所有实例设置一次 class DataFactory url nil def initialize begin if url nil Rails logger debug Setting url url
  • 来自 csv.read 模拟文件的 rspec 测试结果

    我正在使用 ruby 1 9 并且正在尝试执行 BDD 我的第一个测试 应该在 csv 中读取 有效 但第二个测试 我需要模拟文件对象 却不起作用 这是我的型号规格 require spec helper describe Person d
  • Rspec 控制器测试,传递 JSON 参数

    我试图实现以下目标 在 RSpec 控制器测试中创建 POST json 请求 并向其传递参数 这是我的代码 it returns access token do post login email bla password bla1 for
  • RSpec 与 Shoulda?

    我是单元测试场景的新手 我现在只使用单元测试大约两个月了 当我在 Ruby 中进行单元测试时 我目前遵循 TDD 风格并使用 Test Unit TestCase 我还阅读了 RSpec 以及它如何遵循 BDD 方法 我还读过关于 Shou
  • 为什么我必须将 Async 包装到另一个异步工作流程中并让!它?

    我试图了解 F 中的异步工作流程 但我发现有一部分我真的不明白 下面的代码工作正常 let asynWorkflow async let result Stream TryOpenAsync partition gt Async Await
  • Rspec——需要存根在另一个文件中调用的 File.open

    在我的测试中 我正在初始化一个名为的新类Package带有一些参数 在此类的初始化中 我打开一个在远程机器上可用的文件 但不是本地常见的文件 我想知道如何在测试中对该方法进行存根 我正在使用 rspec 和 mocha 我尝试过类似的东西
  • 水豚找不到元标签

    Capybara 2 1 0 似乎没有找到任何元标记 rdb 1 p page find meta Capybara ElementNotFound Exception Unable to find css meta 即使他们出现在page
  • 如何使用 RSpec 检查 JSON 响应?

    我的控制器中有以下代码 format json render json gt flashcard gt flashcard lesson gt lesson success gt true 在我的 RSpec 控制器测试中 我想验证特定场景
  • 如何在服务调用后检查 rspec 中的数组更改?

    目标很简单 例如我们有一个数组 name ghost state rejected name donkey state rejected 运行服务调用后UpdateAllUsers 这会将所有用户更改为 accepted name ghos

随机推荐