Question

I write a mapper which matches attributes received from facebook and set them to my model.

class Mapper::FacebookUser

  def initialize (user, facebook_user)
    @user = user
    @facebook_user = facebook_user
  end

  def name
    @user.name = @facebook_user['name'] if @facebook_user['name'] rescue false
  end
end

The response from Facebook is something like this: (JSON)

{
  "name": "Jo Doe"
}

And my user_spec is that:

require 'spec_helper.rb'

describe Mapper::FacebookUser do

  before(:each) do

    @facebook_user = double("FacebookUser")
    @user = User.new
  end

  it 'should map name to name' do
    @facebook_user.stub(:name).and_return("User Name")
    Mapper::FacebookUser.new(@user, @facebook_user).name
    @user.name.should eq("User Name")
  end
end

RSpec::Mocks::MockExpectationError: Double "Facebook" received unexpected message :[] with ("name")

I tried the following:

    @facebook_user.stub(:name).and_return("User Name")
    @facebook_user.stub("name").and_return("User Name")
    @facebook_user.stub(:[]).and_return({name: "User Name"})
    @facebook_user.stub(:[]).and_return({name: "User Name"}.to_json)

only this one works, but I am quite sure, that's not the way:

    @facebook_user.stub(:[]).and_return("User Name")

What is wrong with my approach? How can I get my test working?

many thanks

I use rspec:

  • rspec (2.14.1)
  • rspec-core (2.14.7)
  • rspec-expectations (2.14.4)
  • rspec-mocks (2.14.4)
  • rspec-rails (2.14.0)
Was it helpful?

Solution 2

My approach is now

I hope this helps someone

facebook_user = {  "name": "Jo Doe" }


class Mapper::FacebookUser

  def initialize (user, facebook_user={})

    @user = user # AR model
    # allows ['key'] or [:keys]
    @facebook_user = facebook_user.with_indifferent_access 
  end

  def name
    @user.name = @facebook_user.dig('name') # sets to nil if not present (works also with chains) >= Ruby 2.3
  end
end


require 'spec_helper.rb'
describe Mapper::FacebookUser do

  before(:each) do
    @user = User.new
    @facebook_user = {}
  end

  it 'should map name to name' do
    @facebook_user['name']
    Mapper::FacebookUser.new(@user, @facebook_user).name
    @user.name.should eq("User Name")
  end
end

OTHER TIPS

First, you're not obviously using @facebook_event in your model, so I'm not sure you're stubbing it. If you want to stub the object/method you are using in your name method, you'd need to stub the :[] method on the @facebook_user object you're passing in on your new call. The reason you're getting the error you're getting is because your not stubbing that method.

I assume the one approach you tried with the @facebook_event stub is working because the real Mapper::FacebookUser#[] method calls that object in that way.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top