RSpec:如何编写单元测试用例以接收在私有方法中引发的异常



我已经为竞争条件实现了乐观锁定。为此,我在产品中添加了一个额外的列lock_version。方法:recalculate调用私有method_1然后保存(save!(产品。我不能在私下method_1中使用save!,因为它会失败其他事情。我不想重构业务逻辑。

#Product: Model's new field:
#  lock_version                       :integer(4)      default(0), not null
def recalculate
method_1
self.save!
end
private
def method_1
begin
####
####
if self.lock_version == Product.find(self.id).lock_version
Product.where(:id => self.id).update_all(attributes)
else
raise ActiveRecord::StaleObjectError.new(self, "test")
end
rescue ActiveRecord::StaleObjectError => e
if tries < 3
tries += 1
sleep(1 + tries)
self.reload
retry
else
raise Exception.new(timeout.inspect)
end
end
end

Rspec 测试用例:

it 'if car is updated then ActiveRecord::StaleObjectError should be raised' do
prod_v1 =Product.find(@prod.id)
prod_v2 = Car.find(@prod.id)
prod_v1.recalculate
prod_v1.reload  # will make lock_version of prod_v1 to 1
prod_v2.recalculate # howvever lock_version of prod_v2 is still 0.
expect(car_v2).to receive(:method1).and_raise(ActiveRecord::StaleObjectError)
end

当我尝试在测试用例上方编写时,它应该引发异常ActiveRecord::StaleObjectError。但是,我收到类似

Failure/Error: expect(car_v2).to receive(:set_total_and_buckets_used).and_raise(ActiveRecord::StaleObjectError)
ArgumentError:
wrong number of arguments (0 for 2)

你可以这样写:

expect(ActiveRecord::StaleObjectError).to receive(:new).and_call_original

因为你正在拯救异常

请务必检查 https://relishapp.com/rspec/rspec-expectations/docs/built-in-matchers

expect(car_v2).to receive(:method1).and_raise(ActiveRecord::StaleObjectError)

意味着当car_v2收到method1时,您不会调用它,但会引发类型ActiveRecord::StaleObjectError的异常。这就是为什么您还会收到 ArgumentError 的原因

使用 rspec,您可以检查特定代码是否引发错误(在您的情况下未处理,它被处理 ->救援...(,如下所示:

expect { my_cool_method }.to raise_error(ErrorClass)

相关内容

  • 没有找到相关文章

最新更新