1

カスタム Bugsnag meta_data (Ruby で Rspec を使用) をどのようにテストしますか?

テストしたいコード:

def do_something
  thing_that_could_error
rescue => e
  Bugsnag.notify(e) do |r|
    r.meta_data = { my_extra_data: "useful info" }
  end
end

私が書きたいテスト:

context "when there's an error" do
  it "calls Bugsnag with my special metadata" do
    expect(Bugsnag).to receive(:notify) # TODO test meta_data values contain "my useful info"
    expect do
      do_something() # exception is thrown and rescued and sent to Bugsnag
    end.not_to raise_error
  end
end

私は使っている:

変数内のデータはmeta_data、この小さな例よりもかなり複雑なので、テストしたいと思います。美しい世界では、そのロジックをヘルパーに抽出してヘルパーをテストしますが、現時点ではその場でテストすることが緊急かつ有用です。

これを理解するために Bugsnag gem の内部 (さらに、さまざまな内部状態と返されたデータをキャプチャするための Rspec-fu) を調べてきましたが、ある時点でインターネットに問い合わせることをお勧めします。

4

1 に答える 1

2

メタデータは複雑なので、単純化することをお勧めします。

def do_something
  thing_that_could_error
rescue => e
  Bugsnag.notify(e) do |r|
    r.meta_data = error_metadata(e, self, 'foo')
  end
end

# I assumed that you'd like to pass exception and all the context
def error_metadata(e, object, *rest)
  BugsnagMetadataComposer.new(e, object, *rest).metadata
end

BugsnagMetadataComposerそのため、初期化方法を完全に制御できる場所 (モックなし) を個別にテストし、metadata出力をテストすることができます。

BugsnagMetadataComposerこれで、必要なオブジェクトでインスタンス化され、metadata呼び出され、ダミーのハッシュを返すことをテストするだけで済みます。

let(:my_exception) { StandardError.new } 
let(:mock_metadata) { Hash.new } 

before do
  # ensure thing_that_could_error throws `my_exception`
expect(BugsnagMetadataComposer)
  .to receive(new)
  .with(my_exception, subject, anything)
  .and_return(mock_metadata)
end

そして難しいのは、メタデータが割り当てられていることを確認することです。これを行うには、少しごまかして、Bugsnag gem がどのようにそれを行っているかを確認します。

どうやらブレッドクラムと呼ばれるものがあるようです:

  let(:breadcrumbs) { Bugsnag.configuration.breadcrumbs }

これにはすべての Bugsnag リクエストがあり、最後のリクエストが一番上にあると思います。したがって、https://github.com/bugsnag/bugsnag-ruby/blob/f9c539670c448f7f129a3f8be7d412e2e824a357/spec/bugsnag_spec.rb#L36-L40と同様のことができます。

specify do 
  do_something()

  expect(breadcrumbs.last.metadata).to eq(expected_metadata)
end

わかりやすくするために、仕様全体は次のようになります。

let(:my_exception) { StandardError.new } 
let(:mock_metadata) { Hash.new } 

before do
  # ensure thing_that_could_error throws `my_exception`
  expect(BugsnagMetadataComposer)
    .to receive(new)
    .with(my_exception, subject, anything)
    .and_return(mock_metadata)
end

specify do 
  do_something()

  expect(breadcrumbs.last.metadata).to eq(expected_metadata)
end
于 2021-01-08T10:26:13.587 に答える