Question

J'ai une application Sinatra qui fournit des pages en lecture seule ou modifiable en fonction de si l'utilisateur est connecté.

Le contrôleur définit une @can_edit variable qui est utilisée par les vues pour masquer / afficher les liens d'édition. Comment puis-je tester la valeur de @can_edit dans mes tests? Je ne sais pas comment obtenir à l'instance actuelle du contrôleur sous rack :: Test.

J'utilise class_eval à bouchonner la méthode logged_in? dans le contrôleur, mais je vais avoir à recourir à la vérification last_response.body pour mes liens d'édition pour voir si @can_edit a été défini ou non.

Comment puis-je tester directement la valeur de @can_edit?

Était-ce utile?

La solution

Malheureusement, je ne pense pas que cela est possible sans modifier rack :: Test. Lorsque vous faites une demande au cours des essais d'application, Rack :: test effectue les opérations suivantes:

  1. ajoute la demande à une liste de demandes récentes
  2. crée une nouvelle instance de votre application et invoque sa méthode call
  3. ajoute la réponse de votre application à une liste des réponses récentes

Il est facile d'accéder à la last_request et last_response, mais malheureusement, aucune information est enregistrée sur l'état de votre application pendant qu'il est en cours d'exécution.

Si vous êtes intéressé par le piratage ensemble un rack :: patch test pour ce faire, commencez par regarder rack-test/lib/rack/mock_session.rb en ligne 30. C'est là rack :: test exécute votre application et reçoit les valeurs standard de retour d'application Rack (statut , en-têtes, corps). Je pense que vous allez devoir modifier votre demande ainsi, de recueillir et de rendre accessibles toutes ses variables d'instance.

Dans tous les cas, il est préférable de tester les résultats, pas de détails de mise en œuvre. Si vous voulez vous assurer un lien d'édition n'est pas visible, test pour la présence du lien d'édition par id DOM:

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

Autres conseils

Il est possible avec un peu de hack. Les cas d'application Sinatra ne sont pas disponibles parce qu'ils sont créés lorsque Sinatra :: Base appel # est appelé. comme expliqué Alex. Ce hack prépare une instance en avant et laisser la prochaine grab appeler.

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

Je compris cette technique raillent l'instance qui exécute le test en cours en premier lieu.

Heres une alternative viable mais méchant

# 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

Cela vous permet de tester contre un avant sinatra instance et filtre ou accès variables créées pour l'application de base.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top