What is the best way to mock a third ruby โ€‹โ€‹object?

I am writing a test application using twitter, and I would like to write an integration test, but I cannot figure out how to mock objects in the Twitter namespace. Here is the function I want to test:

def build_twitter(omniauth) Twitter.configure do |config| config.consumer_key = TWITTER_KEY config.consumer_secret = TWITTER_SECRET config.oauth_token = omniauth['credentials']['token'] config.oauth_token_secret = omniauth['credentials']['secret'] end client = Twitter::Client.new user = client.current_user self.name = user.name end 

and here is the rspec test I'm trying to write:

 feature 'testing oauth' do before(:each) do @twitter = double("Twitter") @twitter.stub!(:configure).and_return true @client = double("Twitter::Client") @client.stub!(:current_user).and_return(@user) @user = double("Twitter::User") @user.stub!(:name).and_return("Tester") end scenario 'twitter' do visit root_path login_with_oauth page.should have_content("Pages#home") end end 

But I get this error:

 1) testing oauth twitter Failure/Error: login_with_oauth Twitter::Error::Unauthorized: GET https://api.twitter.com/1/account/verify_credentials.json: 401: Invalid / expired Token # ./app/models/user.rb:40:in `build_twitter' # ./app/models/user.rb:16:in `build_authentication' # ./app/controllers/authentications_controller.rb:47:in `create' # ./spec/support/integration_spec_helper.rb:3:in `login_with_oauth' # ./spec/integration/twit_test.rb:16:in `block (2 levels) in <top (required)>' 

The above uses rspec, but I'm open to trying moka too. Any help would be greatly appreciated.

Well, I managed to figure it out with every help. Here's the final test:

 feature 'testing oauth' do before(:each) do @client = double("Twitter::Client") @user = double("Twitter::User") Twitter.stub!(:configure).and_return true Twitter::Client.stub!(:new).and_return(@client) @client.stub!(:current_user).and_return(@user) @user.stub!(:name).and_return("Tester") end scenario 'twitter' do visit root_path login_with_oauth page.should have_content("Pages#home") end end 

The trick found out that I needed to stub :configure and :new on real objects and stub :current_user and :name on the dobuled object instance.

+7
source share
2 answers

I think the problem is exactly how you use the layout, you created mock @twitter, but you never use it. I think you might get the impression that any calls to Twitter will use the methods you described, but thatโ€™s not how they work, but only calls made in @twitter will be cut off.

I use double ruby, not rspec mocks, but I believe you want to do something like this:

 Twitter.stub!(:configure).and_return true ... Twitter::Client.stub!(:current_user).and_return @user 

This ensures that at any time the methods that you have imposed on Twitter, Twitter :: Client are called, they respond as you want.

Also, it seems odd that this is verified as part of a view, should really be part of the controller test instead if I don't miss something.

+4
source

You can try using something like http://jondot.github.com/moxy/ . Mock web requirements

0
source

All Articles