1

このテストに合格するのを手伝ってください:

以下は 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

これらのテストを含むフィドルも作成したので、合格させることができます。メソッドのレスキュー ブロックのテストを手伝ってください!


バックグラウンド:

私の元の質問は次のようなものでした:

次のような方法があります。

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ですが、なかなかうまくいきません。

4

2 に答える 2

0

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、プットがレイズするようにスタブします。

これは、仕様が合格している別のフィドルです。

于 2015-08-21T15:55:43.110 に答える