Activerecord创建方法有时无法及时工作

时间:2016-09-23 02:29:53

标签: ruby activerecord rspec

我遇到了以下代码的问题,它只在我运行它时通过了一些时间。

require_relative 'spec_helper'
require 'pry'

RSpec.describe Round do
  testFruit = [Fruit.create(name: "Anjou Pear", unit: "10/LB", price: 13.24), Fruit.create(name: "Anjou Bear", unit: "10/LB", price: 15.24)]

  before(:each) do |variable|
    @round = Round.new
  end

  it 'returns all fruit in the current round of ordering' do
    expect(@round.fruits).to  match_array(testFruit)
  end
  it 'lets you clear the list for the next round' do
    @round.next
    expect(@round.fruits).to match_array([])
  end
end

@round.fruits定义为

def fruits
  Fruits.all
end

所以我理解Fruits.all必须等待testFruits持久化数据库,我猜这是不是及时完成的​​?有没有办法我可以用rspec异步测试它,我应该以不同的方式设计我的测试以避免这个问题吗?

我得到的错误是 ```      失败/错误:期待(@ round.fruits).to match_array(testFruit)

   expected collection contained:  [#<Fruit id: 53, pic: nil, description: nil, name: "Anjou Pear", unit: "10/LB", price: #<BigDecimal:2...l:206de28,'0.1524E2',18(27)>, created_at: "2016-09-27 18:18:23", updated_at: "2016-09-27 18:18:23">]
   actual collection contained:    []

```

1 个答案:

答案 0 :(得分:1)

  

有没有办法可以用rspec

异步测试

是的,但我不会在这里进入,因为如果你以更符合当前最佳实践的方式编写测试,则没有必要。

  

我应该以不同的方式设计我的测试以避免这个问题吗?

是的,这里的问题很可能是由于所谓的&#34;泄漏状态&#34;测试之间。理想的是每个测试应该与每个测试完全隔离,这样您就可以按任何顺序运行测试,并且它们将具有相同的结果。

问题是你刚坐在范围内的testFruit数组。如果更改了此数组或它在数据库中创建的对象,则该更改将泄漏到之后的测试中。

我建议改为写下你的测试:

RSpec.describe Round do
  let!(:round) { Round.new }
  let!(:test_fruit) do
    [
      Fruit.create(name: "Anjou Pear", unit: "10/LB", price: 13.24),
      Fruit.create(name: "Anjou Bear", unit: "10/LB", price: 15.24)
    ]
  end

  describe "#fruits" do
    it 'returns all fruit in the current round of ordering' do
      expect(round.fruits).to match_array(testFruit)
    end
  end

  describe "#next" do
    it 'lets clears the list for the next round' do
      round.next

      expect(round.fruits).to match_array([])
    end
  end
end

这使用了RSpec的let!功能,您可以阅读here。基本上,它确保您在每次测试之间获得一致的设置。

最后,您不必担心有关数据库写入的任何异步问题;在收到数据库中确实写入数据的成功回复之前,Rails不会继续。