【问题标题】:Is there a way to force RSpec to re-evaluate a let statement?有没有办法强制 RSpec 重新评估 let 语句?
【发布时间】:2013-03-24 02:53:00
【问题描述】:

这个例子有点做作,但很好地解释了用例。

let( :number_of_users ){ User.count }

it 'counts users' do
  User.create
  number_of_users.should == 1
  User.create
  number_of_users.should == 2
end

此测试失败,因为 number_of_users 仅被评估一次,并且变得陈旧。有没有办法在每次调用时重新评估它?

【问题讨论】:

  • let() declerations 在第一次被调用时被评估。 number_of_users 应该是一个函数,因为这是您想要的行为。

标签: ruby rspec tdd bdd


【解决方案1】:

你可以只定义一个常规方法:

def number_of_users
  User.count
end

it 'counts users' do
  User.create
  number_of_users.should == 1
  User.create
  number_of_users.should == 2
end

请参阅此blog post 了解更多详细信息,包括如何将辅助方法存储在单独的模块中。

【讨论】:

  • 那个博文链接非常有用。
  • 我没有实现这个解决方案,但它似乎是迄今为止最好的......谢谢。
  • 博文链接现已失效。有人有更新的链接吗?
  • 官方 RSpec 文档不仅包括如何将辅助方法存储在单独的模块中的示例,还包括如何有条件地将它们包含在特定组中的示例。 relishapp.com/rspec/rspec-core/v/3-10/docs/helper-methods/…
【解决方案2】:

这样写测试怎么样:

it "counts user" do
  expect {
    User.create
  }.to change(User, :count).by(1)
end

【讨论】:

  • 是的,这对这个测试会更好。但这是一个简化的例子来解释我想要做什么。真正的测试在这种形式下是less可读的。
  • 提供真实的测试,看看我们是否可以改进它。
【解决方案3】:

简答“不”(AFAIK)

如果你的方法或对象有一个有用的容器,你可以通过给它分配一个变量来获得一些东西。

比你的例子更做作:

let( :user_module ){ User }

it 'counts users' do
  User.create
  user_module.count.should == 1
  User.create
  user_module.count.should == 2
end

【讨论】:

    【解决方案4】:

    你也可以使用proc

    let( :number_of_users ){ proc { User.count } }
    
    it 'counts users' do
      User.create
      number_of_users.call.should == 1
      User.create
      number_of_users.call.should == 2
    end
    

    【讨论】:

    • 感谢这在共享示例中的更改块中很有用,即使我使用 let! 块它也会缓存输出,但 proc 解决方案工作正常,谢谢
    猜你喜欢
    • 2010-10-13
    • 2018-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    • 2013-09-26
    • 1970-01-01
    • 2019-12-13
    相关资源
    最近更新 更多