2011-11-29 20 views
7

Sto scrivendo un'app di test utilizzando la gemma di Twitter e vorrei scrivere un test di integrazione ma non riesco a capire come imitare gli oggetti nello spazio dei nomi di Twitter. Ecco la funzione che voglio prova:Qual è il modo migliore per deridere un oggetto di terze parti in 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 

ed ecco il test RSpec che sto cercando di scrivere:

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 

Ma, sto ottenendo questo errore:

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

I mock qui sopra stanno usando rspec ma sono aperto anche a provare la moka. Qualsiasi aiuto sarebbe molto apprezzato.

OK, sono riuscito a capirlo grazie all'aiuto di tutti. Ecco la prova finale:

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 

Il trucco era capire che avevo bisogno di stub :configure e :new sugli oggetti reali e stub :current_user e :name su un'istanza di oggetto dobuled.

risposta

4

Penso che il problema sia proprio il modo in cui si sta usando la simulazione, si è creato il simulato @twitter, ma non lo si usa mai realmente. Penso che potresti avere l'impressione che qualsiasi chiamata a Twitter utilizzi i metodi di prova specificati, ma non è così che funziona, solo le chiamate fatte a @twitter vengono stubate.

Io uso doppia rubino, deride non RSpec, ma credo che si vuole fare qualcosa di simile a questo, invece:

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

Questo assicura che ogni volta che i metodi che si spense su Twitter, Twitter :: client sono chiamati, rispondono come vuoi.

Inoltre, sembra strano che questo sia testato come parte di una vista, dovrebbe invece essere parte di un test del controller, a meno che manchi qualcosa.

+0

Sì! Grazie. Hai esattamente ragione che mi mancava la differenza tra lo stub di un metodo sul modello e lo stub di un'istanza che è stata raddoppiata. Grazie a questo sono stato in grado di capirlo. Modificherò la domanda per includere come ho finalmente risolto questo problema. – spinlock

Problemi correlati