2011-11-29 16 views
7

Estoy escribiendo una aplicación de prueba usando la gema de twitter y me gustaría escribir una prueba de integración, pero no puedo encontrar la manera de burlarme de los objetos en el espacio de nombres de Twitter. Aquí está la función que quiero prueba:¿Cuál es la mejor manera de burlarse de un objeto de terceros en 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 

y aquí está la prueba de rspec que estoy tratando de escribir:

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 

Pero, estoy recibiendo este 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)>' 

Los simulacros de arriba están usando rspec, pero también estoy dispuesto a probar mocha. Cualquier ayuda sería muy apreciada.

OK, me las arreglé para resolver esto gracias a la ayuda de todos. Aquí está la prueba final:

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 

El truco era averiguar que necesitaba código auxiliar :configure y :new en los objetos reales y golpeo :current_user y :name en una instancia de objeto dobuled.

Respuesta

4

Creo que el problema es solo la forma en que está utilizando el simulacro, creó el simulador @twitter, pero en realidad nunca lo usa. Creo que puede tener la impresión de que cualquier llamada a Twitter utilizará los métodos restringidos que haya especificado, pero no es así como funciona, solo se interceptan las llamadas realizadas a @twitter.

utilizo doble rubí, se burla no rspec, pero creo que quiere hacer algo como esto en su lugar:

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

Esto asegura que en cualquier momento los métodos que se apagó en Twitter, Twitter :: Cliente son llamados, responden como quieres

Además, parece extraño que esto se pruebe como parte de una vista, en realidad debería ser parte de una prueba de controlador a menos que me falta algo.

+0

Sí! Gracias. Tiene razón en que me estaba perdiendo la diferencia entre anotar un método en el modelo y anular una instancia que se duplicó. Gracias a esto pude resolverlo. Editaré la pregunta para incluir cómo finalmente resolví esto. – spinlock

Cuestiones relacionadas