2014-01-26 25 views
1

我想测试我的控制器只是调用服务对象的方法。我认为一个测试间谍会是完美的。我究竟做错了什么?谢谢你的帮助!如何在控制器测试中使用简单的测试间谍?

控制器:

class PostsController < ApplicationController 

    def create 
    @post = Post.new(post_params) 

    if @post.save 
     ServiceObject.new(@post).call 
     redirect_to posts_path, success: "#{@post.title} was successfully created." 
    else 
     render action: :new 
    end 
    end 

end 

服务对象:

class ServiceObject 

    def initialize(post) 
    @post = post 
    end 

    def call 
    puts "Service object was called!" 
    end 

end 

控制器测试:

require 'spec_helper' 

describe PostsController do 
    describe 'POST #create' do 
    it 'calls the service object' do 
     service_object = double(ServiceObject) 
     service_object.stub(:new).and_return(service_object) 
     service_object.stub(:call) 
     post :create, post: Fabricate.attributes_for(:post) 
     expect(service_object).to have_received(:call) 
    end 
    end 
end 

错误:

Failure/Error: expect(service_object).to have_received(:call) 
    (Double ServiceObject).call(any args) 
     expected: 1 time with any arguments 
     received: 0 times with any arguments 
+0

你检查该职位被保存和'''如果@ post.save'''被返回true –

回答

1

试试这个:

require 'spec_helper' 

describe PostsController do 
    describe 'POST #create' do 
    let(:service_object) { double(:service_object) } 

    before do 
     ServiceObject.stub(:new).and_return(service_object) 
     service_object.stub(:call) 
    end 

    it 'calls the service object' do 
     post :create, post: Fabricate.attributes_for(:post) 

     expect(service_object).to have_received(:call) 
    end 
    end 
end 
+0

那么这工作!我看到的主要区别在于我创建double的方式:“double(ServiceObject)”vs“double(:service_object)”。可能需要返回并重新访问双打。谢谢! –

+0

是的,这是正确的 - 这是关键的区别...这是创建一个模拟对象,由关键“':service_object'''确定......然后我们必须存根”'''''''''''''''''''' '''方法来返回模拟对象,我们依次在其上存根'''调用'',然后建立它接收到消息'''call'''的期望 –