Pregunta

Tengo una aplicación que sirve Sinatra páginas como de sólo lectura o modificable en función de si el usuario ha iniciado sesión.

El controlador establece un @can_edit variables, que es utilizado por los puntos de vista para ocultar editar enlaces / mostrar. ¿Cómo puedo probar el valor de @can_edit en mis pruebas? No tengo ni idea de cómo llegar a la instancia actual del controlador bajo el estante :: prueba.

Yo uso class_eval al stub del método logged_in? en el controlador, pero estoy teniendo que recurrir a la comprobación last_response.body para mis editar enlaces para ver si @can_edit se ha establecido o no.

¿Cómo puedo probar el valor de @can_edit directamente?

¿Fue útil?

Solución

Por desgracia, no creo que esto es posible sin modificar rack :: prueba. Cuando se hace una solicitud durante las pruebas de aplicaciones, Cambio :: prueba consiste en lo siguiente:

  1. añade la solicitud a una lista de peticiones recientes
  2. Crea una nueva instancia de la aplicación e invoca su método call
  3. añade la respuesta de su aplicación a una lista de respuestas recientes

Es fácil acceder al last_request y last_response, pero por desgracia no se guardará información sobre el estado de su aplicación mientras se está ejecutando.

Si está interesado en la piratería en conjunto un parche rack :: Prueba de ello, empezar por mirar rack-test/lib/rack/mock_session.rb en la línea 30. Aquí es donde rack :: Prueba ejecuta la aplicación y recibe los valores de retorno aplicación rack estándar (estado , cabeceras, cuerpo). Mi conjetura es que usted va a tener que modificar la aplicación, así, para recoger y hacer accesibles de sus variables de instancia.

En cualquier caso, lo mejor es poner a prueba a los resultados, no los detalles de implementación. Si desea asegurarse de que un enlace de edición no es visible, la prueba de la presencia del enlace de edición de DOM id:

assert last_response.body.match(/<a href="..." id="...">/)

Otros consejos

Es posible con un pequeño truco. casos de Sinatra aplicaciones no están disponibles porque se crean cuando Sinatra :: Base # llamada se llama. como se explica Alex. Este truco se prepara una instancia en adelante y dejar que la siguiente llamada agarrarlo.

require 'something/to/be/required'

class Sinatra::Base
  @@prepared = nil

  def self.onion_core
    onion = prototype
    loop do
      onion = onion.instance_variable_get('@app')
      return onion if onion.class == self || onion.nil?
    end
  end

  def self.prepare_instance
    @@prepared = onion_core
  end

  # Override
  def call(env)
    d = @@prepared || dup
    @@prepared = nil
    d.call!(env)
  end
end

describe 'An Sinatra app' do
  include Rack::Test::Methods

  def app
    Sinatra::Application
  end

  it 'prepares an app instance on ahead' do
    app_instance = app.prepare_instance    
    get '/foo'
    app_instance.instance_variable_get('@can_edit').should be_true
  end
end

Me di cuenta de que esta técnica burlan de la instancia que dirige el prueba actual en el primer lugar.

Aquí está una alternativa viable, pero desagradable

# app.rb - sets an instance variable for all routes
before do
  @foo = 'bar'
end

# spec.rb
it 'sets an instance variable via before filter' do
  my_app = MySinatraApplication
  expected_value = nil
  # define a fake route
  my_app.get '/before-filter-test' do
    # as previously stated, Sinatra app instance isn't avaiable until #call is performed
    expected_value = @foo
  end
  my_app.new.call({
    'REQUEST_METHOD' => 'GET',
    'PATH_INFO' => '/before-filter-test',
    'rack.input' => StringIO.new
  })
  expect(expected_value).to eq('bar')
end

Esto le permite probar contra un Sinatra antes de variables de filtro y de instancia o de acceso creado para la aplicación de base.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top