如何使用 rspec mocks 3.3 测试方法的救援块
How do I test the rescue block of a method with rspec mocks 3.3
帮我通过这个测试:
这里是一些rspec代码的例子,
class User
attr_accessor :count
def initialize
@count = 0
end
# sometimes raises
def danger
puts "IO can be dangerous..."
rescue IOError => e
@count += 1
end
#always raises
def danger!
raise IOError.new
rescue IOError => e
@count += 1
end
end
describe User do
describe "#danger!" do
it "its rescue block always increases the counter by one" do
allow(subject).to receive(:'danger!')
expect {
subject.danger!
}.to change(subject, :count).by(1)
end
end
describe "#danger" do
context "when it rescues an exception" do
it "should increase the counter" do
allow(subject).to receive(:danger).and_raise(IOError)
expect {
subject.danger
}.to change(subject, :count).by(1)
end
end
end
end
我还创建了一个包含这些测试的 fiddle,因此您可以让它们通过。请帮我测试一个方法的救援块!
背景:
我原来的问题是这样的:
我有一个方法,如下所示:
def publish!(resource)
published_resource = resource.publish!(current_project)
resource.update(published: true)
if resource.has_comments?
content = render_to_string partial: "#{ resource.class.name.tableize }/comment", locals: { comment: resource.comment_content_attributes }
resource.publish_comments!(current_project, published_resource.id, content)
end
true
rescue Bcx::ResponseError => e
resource.errors.add(:base, e.errors)
raise e
end
我想测试 resource.errors.add(:base, e.errors)
实际上是在向资源添加错误。更一般地说,我想在一个方法中测试救援块。
所以我想写这样的代码,
it "collects errors" do
expect{
subject.publish!(training_event.basecamp_calendar_event)
}.to change(training_event.errors.messages, :count).by(1)
end
当然,这会引发错误,因为我在救援区再次加注。
我看到一些使用旧 something.stub(:method_name).and_raise(SomeException)
的答案,但 rspec 抱怨说这种语法已被弃用。我想使用 Rspec Mocks 3.3 和 allow
语法,但我遇到了困难。
allow(something).to receive(:method_name).and_raise(SomeException)
将是新的 allow
语法。查看 the docs 以供参考。
我误解了 allow
语法的实际用途。所以为了让我的示例规范通过,我需要这样做:
describe "#danger" do
context "when it rescues an exception" do
it "should increase the counter" do
allow($stdout).to receive(:puts).and_raise(IOError) # <----- here
expect {
subject.danger
}.to change(subject, :count).by(1)
end
end
end
我存根的不是方法,也不是主题,而是可能引发的对象。在这种情况下,我存根 $stdout
以便看跌期权会加注。
这是另一个fiddle,其中规范通过。
帮我通过这个测试:
这里是一些rspec代码的例子,
class User
attr_accessor :count
def initialize
@count = 0
end
# sometimes raises
def danger
puts "IO can be dangerous..."
rescue IOError => e
@count += 1
end
#always raises
def danger!
raise IOError.new
rescue IOError => e
@count += 1
end
end
describe User do
describe "#danger!" do
it "its rescue block always increases the counter by one" do
allow(subject).to receive(:'danger!')
expect {
subject.danger!
}.to change(subject, :count).by(1)
end
end
describe "#danger" do
context "when it rescues an exception" do
it "should increase the counter" do
allow(subject).to receive(:danger).and_raise(IOError)
expect {
subject.danger
}.to change(subject, :count).by(1)
end
end
end
end
我还创建了一个包含这些测试的 fiddle,因此您可以让它们通过。请帮我测试一个方法的救援块!
背景:
我原来的问题是这样的:
我有一个方法,如下所示:
def publish!(resource)
published_resource = resource.publish!(current_project)
resource.update(published: true)
if resource.has_comments?
content = render_to_string partial: "#{ resource.class.name.tableize }/comment", locals: { comment: resource.comment_content_attributes }
resource.publish_comments!(current_project, published_resource.id, content)
end
true
rescue Bcx::ResponseError => e
resource.errors.add(:base, e.errors)
raise e
end
我想测试 resource.errors.add(:base, e.errors)
实际上是在向资源添加错误。更一般地说,我想在一个方法中测试救援块。
所以我想写这样的代码,
it "collects errors" do
expect{
subject.publish!(training_event.basecamp_calendar_event)
}.to change(training_event.errors.messages, :count).by(1)
end
当然,这会引发错误,因为我在救援区再次加注。
我看到一些使用旧 something.stub(:method_name).and_raise(SomeException)
的答案,但 rspec 抱怨说这种语法已被弃用。我想使用 Rspec Mocks 3.3 和 allow
语法,但我遇到了困难。
allow(something).to receive(:method_name).and_raise(SomeException)
将是新的 allow
语法。查看 the docs 以供参考。
我误解了 allow
语法的实际用途。所以为了让我的示例规范通过,我需要这样做:
describe "#danger" do
context "when it rescues an exception" do
it "should increase the counter" do
allow($stdout).to receive(:puts).and_raise(IOError) # <----- here
expect {
subject.danger
}.to change(subject, :count).by(1)
end
end
end
我存根的不是方法,也不是主题,而是可能引发的对象。在这种情况下,我存根 $stdout
以便看跌期权会加注。
这是另一个fiddle,其中规范通过。