2012-12-07 91 views
0

可以說我的rails應用程序中有一個服務類。它的作用並不重要,但讓我們假設它可以用於推送通知給客戶端。從Rails環境中解耦服務類

# 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。當我運行測試時,我不希望發生這種情況。

我看到它的方式我有兩種選擇。

選項1:
我一定要記住所有呼叫的postfix EventPusher.trigger與環境檢查。請記住,我可以在我的應用程序的每個創建/更新/銷燬操作中調用此操作。

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

選項2:
我有幾個我的服務類軌。

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

這是正確的選項(或者是否有一個祕密選項編號3)?

回答

1

您是否在使用RSpec?如果是這樣,您可以覆蓋EventPusher的發佈方法的功能測試本身裏面,像這樣:

EventPusher.any_instance.stub(:publish) 

上面的代碼替換原來的發佈方法與返回nil空的方法。該方法依然存在,仍然會被調用,但它在測試範圍內不會做任何事情。

如果其他代碼期待的發佈方法返回的東西,如「真」表示成功,那麼你可以添加以下內容:

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

或者,如果你願意重寫PusherGem的靜態觸發器方法,然後使用此稍微不同的語法:

PusherGem.stub!(:trigger) 

PusherGem.stub!(:trigger).and_return("something here, perhaps?")