Prueba de variables de instancia del controlador con rack :: Prueba y Sinatra
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?
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:
- añade la solicitud a una lista de peticiones recientes
- Crea una nueva instancia de la aplicación e invoca su método
call
- 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.