Rspec: 如何测试引发错误的方法
Rspec: How to test a method that raises an error
我有一个 SubscriptionHandler class,它的调用方法可以创建待定订阅,尝试向用户收费,然后在收费失败时出错。无论计费是否失败,都会创建待定订阅
class SubscriptionHandler
def initialize(customer, stripe_token)
@customer = customer
@stripe_token = stripe_token
end
def call
create_pending_subscription
attempt_charge!
upgrade_subscription
end
private
attr_reader :stripe_token, :customer
def create_pending_subscription
@subscription = Subscription.create(pending: true, customer_id: customer.id)
end
def attempt_charge!
StripeCharger.new(stripe_token).charge! #raises FailedPaymentError
end
def upgrade_subscription
@subscription.update(pending: true)
end
end
这是我的规格:
describe SubscriptionHandler do
describe "#call" do
it "creates a pending subscription" do
customer = create(:customer)
token = "token-xxx"
charger = StripeCharger.new(token)
allow(StripeCharger).to receive(:new).and_return(charger)
allow(charger).to receive(:charge!).and_raise(FailedPaymentError)
handler = SubscriptionHandler.new(customer, token)
expect { handler.call }.to change { Subscription.count }.by(1) # Fails with FailedPaymentError
end
end
end
但这不会更改订阅计数,它会因 FailedPaymentError 而失败。有没有一种方法可以检查订阅计数是否增加,而规范不会因 FailedPaymentError 而崩溃。
可以这样做
expect{ handler.call }.to raise_error FailedPaymentError
应该可以。
如果您根本不想引发错误,那么您可以删除此行,并 return 一个有效的响应
allow(charger).to receive(:charge!).and_raise(FailedPaymentError)
更多信息 - How to test exception raising in Rails/RSpec?
官方RSpec文档
https://relishapp.com/rspec/rspec-expectations/v/2-0/docs/matchers/expect-error
您应该能够对此使用 Rspec 复合期望
https://relishapp.com/rspec/rspec-expectations/docs/compound-expectations
所以我会把你的期望重写成这样:
expect { handler.call }.
to raise_error(FailedPaymentError).
and change { Subscription.count }.by(1)
我有一个 SubscriptionHandler class,它的调用方法可以创建待定订阅,尝试向用户收费,然后在收费失败时出错。无论计费是否失败,都会创建待定订阅
class SubscriptionHandler
def initialize(customer, stripe_token)
@customer = customer
@stripe_token = stripe_token
end
def call
create_pending_subscription
attempt_charge!
upgrade_subscription
end
private
attr_reader :stripe_token, :customer
def create_pending_subscription
@subscription = Subscription.create(pending: true, customer_id: customer.id)
end
def attempt_charge!
StripeCharger.new(stripe_token).charge! #raises FailedPaymentError
end
def upgrade_subscription
@subscription.update(pending: true)
end
end
这是我的规格:
describe SubscriptionHandler do
describe "#call" do
it "creates a pending subscription" do
customer = create(:customer)
token = "token-xxx"
charger = StripeCharger.new(token)
allow(StripeCharger).to receive(:new).and_return(charger)
allow(charger).to receive(:charge!).and_raise(FailedPaymentError)
handler = SubscriptionHandler.new(customer, token)
expect { handler.call }.to change { Subscription.count }.by(1) # Fails with FailedPaymentError
end
end
end
但这不会更改订阅计数,它会因 FailedPaymentError 而失败。有没有一种方法可以检查订阅计数是否增加,而规范不会因 FailedPaymentError 而崩溃。
可以这样做
expect{ handler.call }.to raise_error FailedPaymentError
应该可以。
如果您根本不想引发错误,那么您可以删除此行,并 return 一个有效的响应
allow(charger).to receive(:charge!).and_raise(FailedPaymentError)
更多信息 - How to test exception raising in Rails/RSpec?
官方RSpec文档
https://relishapp.com/rspec/rspec-expectations/v/2-0/docs/matchers/expect-error
您应该能够对此使用 Rspec 复合期望
https://relishapp.com/rspec/rspec-expectations/docs/compound-expectations
所以我会把你的期望重写成这样:
expect { handler.call }.
to raise_error(FailedPaymentError).
and change { Subscription.count }.by(1)