2011-11-29 52 views
7

我正在使用twitter gem编写一个测试应用程序,我想编写一个集成测试,但我无法弄清楚如何模拟Twitter命名空间中的对象。下面是我想测试功能:在ruby中模拟第三方对象的最佳方法是什么?

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 

和这里的,我试图写RSpec的测试:

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 

但是,我得到这个错误:

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)>' 

上面的模拟使用rspec,但我也愿意尝试摩卡。任何帮助将不胜感激。

好的,我得到了大家的帮助,得出了这个结论。下面是最终测试:

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 

诀窍是搞清楚,我需要存根上的实物:configure:new并在dobuled对象实例存根:current_user:name

回答

4

我认为问题就在于你使用模拟的方式,你创建了模拟@twitter,但你从来没有真正使用它。我认为你可能会觉得任何对Twitter的调用都会使用你指定的存根方法,但这不是它的工作方式,只有对@twitter的调用被存根。

我使用双红宝石,不是RSpec的嘲弄,但我相信你想要做这样的事情,而不是:

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

这可以确保任何时候你在Twitter上存根方法,微博客户端::调用,他们回应你的想法。

此外,这似乎很奇怪,这是作为一个视图的一部分进行测试,应该真的是控制器测试的一部分,而不是我失去了一些东西。

+0

是的!谢谢。你完全正确,我错过了在模型上对方法进行存根与对已加倍的实例进行存根之间的区别。多亏了这个,我才弄明白了。我会编辑这个问题,包括我最终如何解决这个问题。 – spinlock

相关问题