Rspec 3.8 前块不删除记录

Rspec 3.8 before block not deleting record

app/models/car.rb 中,class 方法 stock 部分看起来像这样:

 def self.stock
   raise Exception, "Property amount not set" if Property.get(:amount).nil?
   ...
 end

用户可以通过所有 CRUD 操作访问此 属性。 我现在想测试一下 属性 是否真的被删除了,应该抛出一个标准的期望值。因此,我在我的 rspec 模型中创建了以下示例组

describe '.stock' do

  describe 'if property is not set' do
    before(:all) {Property.where(name: 'amount').map(&:destroy)}
    it 'raises an exception' do
      expect{Car.stock}.to raise_error (Exception)
    end 
    after (:all) {Property.create! name: 'amount', value: 10}
  end 

  describe 'if property is set' do
    before (:all) do  
      create :car_listed
      create :car_sold
    end 
    it 'calculates the correct amount of sellable cars' do
      amount = 10 - Car.where(state: "sold")
      expect(Car.stock).to eq(amount)
    end 
  end 
end 

我确保删除所有具有该名称的属性。在 it-block 中,我希望异常被处理。在 it-block 之后我再次创建了 属性 因为其他测试依赖于它。

应用程序中的属性在测试期间不会更改。所以 database_cleaner 不会截断属性 table。它是通过种子文件设置的。

config.before(:suite) do
  DatabaseCleaner.strategy = :truncation, {except: %w[properties]}
end

但是测试失败

Car
 .stock
   if property is set
    calculates the correct amount of sellable cars
   if property is not set
    raises an exception (FAILED - 1)

 Failures:

  1) Car.stock if property is not set not set raises an exception
      Failure/Error: expect{Car.stock}.to raise_error (Exception)
      expected Exception but nothing was raised
      # ./spec/models/car_spec.rb: `block (4 levels) in <top (required)>'

我现在的问题是我必须如何正确删除此 属性 ((:),以便引发异常。

有不接触数据库的更简单的测试方法。以下是使用存根解决问题的方法:

describe '.stock' do
  before do
    allow(Property).to receive(:get).with(:amount).and_return(amount)
  end

  context 'when property amount is NOT set' do
    let(:amount) { nil }

    it 'raises an exception' do
      expect { Car.stock }.to raise_error(Exception)
    end
  end

  context 'when amount property is set' do
    let(:amount) { 10 }

    before do
      create :car_listed
      create :car_sold
    end

    it 'does NOT raise an exception' do
      expect { Car.stock }.to_not raise_error(Exception)
    end

    it 'calculates the correct amount of sellable cars' do
      expect(Car.stock).to eq(amount - 1)
    end 
  end

注意:我不确定最后一个测试,因为您没有包含该代码。