2012-12-07 93 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?")