2011-11-29 6 views
7

Piszę aplikację testową za pomocą klejnotu twitter i chciałbym napisać test integracji, ale nie mogę wymyślić, jak kpić z obiektów w przestrzeni nazw Twittera. Oto funkcja, że ​​chcę testu:Jaki jest najlepszy sposób na wyśmiewanie obiektu innej firmy w 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 

i oto rspec test, który staram się napisać:

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 

Ale ja dostaję ten błąd:

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

Powyższe makiety używają rspec, ale jestem też otwarty na próbę mocha. Każda pomoc będzie bardzo ceniona.

OK, udało mi się to zrozumieć dzięki pomocy wszystkich. Oto test końcowy:

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 

Sztuką było dowiedzieć się, że muszę skrótową :configure i :new na rzeczywistych obiektach i skrótową :current_user i :name na dobuled instancji obiektu.

Odpowiedz

4

Myślę, że problemem jest właśnie sposób, w jaki używasz makiety, stworzyłeś makiety @twitter, ale nigdy go nie używasz. Wydaje mi się, że możesz mieć wrażenie, że wszelkie połączenia z Twitterem będą korzystać z wybranych przez Ciebie metod, ale to nie działa, a tylko połączenia wykonane z @twitter są zgaszone.

używam podwójnego rubin, nie rspec mocks, ale wierzę, chcesz zrobić coś takiego zamiast:

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

To gwarantuje, że w każdej chwili możesz zgaszone sposoby na Twitter, Twitter :: Client są nazywane, odpowiadają, jak chcesz.

Wydaje się dziwne, że jest to testowane jako część widoku, naprawdę powinno być częścią testu kontrolera, chyba że czegoś brakuje.

+0

Tak! Dziękuję Ci. Masz całkowitą rację, że brakowało mi różnicy między odgadywaniem metody na modelu i niedotrzymywaniem instancji, która została podwojona. Dzięki temu udało mi się to rozgryźć. Zmienię to pytanie, aby wyjaśnić, jak w końcu to rozwiązałem. – spinlock

Powiązane problemy