在app/models/car.rb
中,类方法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
我确保所有具有该名称的属性都将被删除。然后,我希望在它的代码块中抛出异常。在它块之后,我再次创建了该属性,因为其他测试依赖于它。
应用程序中的属性在测试期间不会更改。因此database_cleaner
不会截断属性表。它是通过种子文件设置的。
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)>'
我的问题是,现在我该如何正确删除此属性((:),以便引发我的异常。
答案 0 :(得分:0)
有更简单的方法可以测试此方法,而不会影响数据库。这是使用存根解决问题的方法:
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
注意:由于您未包含该代码,因此我不确定最后一次测试。