Question

I'm trying to test that my controller simply calls a method on a service object. I thought a test spy would be perfect for this. What am I doing wrong? Thanks for any help!

Controller:

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

Service object:

class ServiceObject

  def initialize(post)
    @post = post
  end

  def call
    puts "Service object was called!"
  end

end

Controller test:

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

Error:

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
Was it helpful?

Solution

try this:

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top