Domanda

Ho un app Sinatra che serve pagine come di sola lettura o modificabili a seconda se l'utente è collegato.

Il controllore imposta un @can_edit variabile, che viene utilizzato da punti di vista per nascondere / mostrare modificare i collegamenti. Come faccio a testare il valore di @can_edit nel mio test? Non ho idea di come arrivare alla istanza corrente del controller in rack :: Test.

Io uso class_eval stub metodo logged_in? nel controller, ma sto dover ricorrere al controllo last_response.body per la mia modifica link per vedere se @can_edit è stata impostata o meno.

Come faccio a verificare il valore di @can_edit direttamente?

È stato utile?

Soluzione

Purtroppo non credo che questo sia possibile senza modificare Rack :: Test. Quando si effettua una richiesta durante il testing delle applicazioni, Rack :: Test esegue le seguenti operazioni:

  1. aggiunge la richiesta di un elenco di recenti richieste
  2. crea una nuova istanza dell'applicazione e invoca il suo metodo call
  3. aggiunge risposta dell'applicazione ad un elenco di risposte recenti

E 'facile accedere al last_request e last_response, ma purtroppo nessuna informazione viene salvata sullo stato della vostra applicazione mentre è in esecuzione.

Se siete interessati a l'hacking insieme una patch rack :: Test per fare questo, iniziare a guardare rack-test/lib/rack/mock_session.rb on line 30. Questo è dove Rack :: Test esegue l'applicazione e riceve i valori Rack applicazione di ritorno standard di (stato , intestazioni, corpo). La mia ipotesi è che si sta andando ad avere per modificare l'applicazione e, di raccogliere e rendere tutte le sue variabili di istanza accessibile.

In ogni caso, è meglio per testare i risultati, non i dettagli di implementazione. Se si vuole fare in modo un link di modifica non è visibile, test per la presenza del collegamento modifica di DOM ID:

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

Altri suggerimenti

E 'possibile con un piccolo hack. casi di Sinatra app non sono disponibili perché vengono creati quando Sinatra :: Base # chiamata viene chiamato. come spiegato Alex. Questo mod prepara un'istanza avanti e lasciare che la chiamata successiva afferrarlo.

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

ho capito questa tecnica per deridere l'istanza che gestisce il test in corso in primo luogo.

Ecco una brutta ma valida alternativa

# 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

Questo vi permette di testare contro un Sinatra prima di filtro e o di istanza di accesso variabili create per l'applicazione di base.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top