6

この質問はこれと重複しているように見えるかもしれませんが、受け入れられた回答は私の問題には役立ちません。

環境

Rails 5 では、コントローラー テスト (現在は ActionDispatch::IntegrationTest から継承されています) でセッションを直接操作することはサポートされていないため、モック化とスタブ化という暗い道をたどっています。

これは悪い習慣であり、コントローラーをテストするためのより良い方法があることは知っています (そして、統合テストへの移行を理解しています) が、完全な統合テストを実行して、設定するためだけに 1 つのテストで複数のアクションを呼び出したくありません。特定のセッション変数。

シナリオ

Mochaを使用すると、セッション変数のモック/スタブは実際には非常に簡単です。

ActionDispatch::Request::Session.any_instance.stubs(:[]).with(:some_variable).returns("some value")

問題は、Railsがセッション内に多くのものを保存しsession.inspect(ビューの 1 つのどこかで実行するだけ)、:[]メソッドをスタブ化すると明らかにそれらのいずれにもアクセスできなくsession[:some_other_variable]なることです (したがって、テストでは機能しなくなります)。

質問

:[]特定のパラメーターで呼び出された場合にのみメソッドをスタブ/モックし、他のすべての呼び出しをスタブ化しない方法はありますか?

私は何かを望んでいただろう

ActionDispatch::Request::Session.any_instance.stubs(:[]).with(:some_variable).returns("some value")
ActionDispatch::Request::Session.any_instance.stubs(:[]).with(anything).returns(original_value)

しかし、私はそれを成し遂げる方法を見つけることができませんでした。

4

1 に答える 1

1

私が見たところ、これはモカでは利用できない機能です

https://github.com/freerange/mocha/issues/334

私はこれが存在することを知っていますrspec-mock

https://github.com/rspec/rspec-mocks/blob/97c972be57f2c060a4a7fb8a3c5700a5ede693f0/spec/rspec/mocks/stub_implementation_spec.rb#L29

ただし、元のセッションをオブジェクトに保存し、コントローラーがセッションを受信するたびに別のモックオブジェクトを返すことをモックします。これにより、モックされたベルを返すか、呼び出しを委任することができます。元のセッションへ

class MySession
  def initialize(original)
    @original = original
  end
  def [](key)
    if key == :mocked_key
      2
    else
      original[key]
    end
  end
end

let!(original_session) { controller.send(:session) }
let(:my_session) { MySession.new(original_session) }

before do
  controller.stubs(:session) { my_session }
end

mocha ではブロック モッキングもできるので、クラスは必要ありませんが、それoriginal_sessionを呼び出す必要があると思います。

しかし、きれいな方法がわかりません

于 2021-05-24T21:22:41.670 に答える