0

私のレールアプリにサービスクラスがあるとしましょう。それが何をするかは問題ではありませんが、クライアントに通知をプッシュするために使用できると仮定しましょう。

# lib/services/event_pusher.rb
class EventPusher
  def initialize(client)
    @client = client
  end

  def publish(event)
    PusherGem.trigger(@client, event)
  end
end

コントローラーでこのクラスを使用できるようになりました。

require "lib/services/event_pusher"

class WhateverController < ApplicationController
  def create
    @whatever = Whatever.new(params[:whatever])

    if @whatever.save
      EventPusher.new(current_user).publish('whatever:saved')
    end
  end
end

を呼び出すと、このサービス クラスはサード パーティにリクエストを送信しますpublish。テストを実行しているときにそれが発生したくありません。

私の見方では、2 つの選択肢があります。

オプション 1:
へのすべての呼び出しをEventPusher.trigger環境チェックで後置することを覚えておく必要があります。アプリのすべての作成/更新/破棄アクションでこれを呼び出すことができることを思い出してください。

if @whatever.save
  EventPusher.new(current_user).publish('whatever:saved') unless Rails.env.test?
end

オプション 2:
サービス クラスを Rails に結合する必要があります。

def publish(event)
  PusherGem.trigger(@client, event) unless Rails.env.test?
end

正しいオプションはどれですか (または、秘密のオプション番号 3 はありますか)?

4

1 に答える 1

1

RSpecを使用していますか?その場合、次のように、テスト自体の内部で EventPusher の publish メソッドの機能をオーバーライドできます。

EventPusher.any_instance.stub(:publish)

上記のコードは、元の publish メソッドを、nil を返す空のメソッドに置き換えます。メソッドはまだ存在し、呼び出されますが、テストの範囲内では何もしません。

成功を示す「true」など、publish メソッドが何かを返すことを他のコードが期待している場合は、次を追加できます。

EventPusher.any_instance.stub(:publish).and_return(true)

または、PusherGem の静的トリガー メソッドをオーバーライドしたい場合は、次のわずかに異なる構文を使用します。

PusherGem.stub!(:trigger)

また

PusherGem.stub!(:trigger).and_return("something here, perhaps?")
于 2012-12-07T11:28:41.717 に答える