Frage

Ich habe eine Sinatra-Anwendung, die Seiten als schreibgeschützte oder editierbare dient je nachdem, ob der Benutzer angemeldet ist.

Der Controller setzt eine Variable @can_edit, die von den Ansichten zu hide / show bearbeiten Links verwendet wird. Wie kann ich @can_edit Wert in meinen Tests testen? Ich habe keine Ahnung, wie in der aktuellen Instanz des Controllers unter Rack bekommen :: Test.

Ich verwende class_eval die logged_in? Methode in der Steuerung Stummel, aber ich habe auf die Überprüfung last_response.body für meine bearbeiten Links greifen, um festzustellen, ob @can_edit gesetzt wurde oder nicht.

Wie kann ich den Wert von @can_edit testen direkt?

War es hilfreich?

Lösung

Leider nicht ich denke, das ist möglich, ohne Rack-modifizierende :: Tests. Wenn Sie eine Anforderung bei Anwendungstests machen, Schärfen :: Test macht folgendes:

  1. fügt die Anforderung an eine Liste der letzten Anfragen
  2. erstellt eine neue Instanz der Anwendung und ruft seine call Methode
  3. fügt Ihre Anwendung Antwort auf eine Liste der letzten Antworten

Es ist einfach, den Zugang der last_request und last_response, aber leider keine Informationen über den Zustand Ihrer Anwendung gespeichert, während es läuft.

Wenn Sie in Hacking zusammen ein Rack-interessiert sind :: Test-Patch, dies zu tun, starten Sie durch in rack-test/lib/rack/mock_session.rb auf Linie 30. Diese Suche ist, wo Rack-:: Testen Sie Ihre Anwendung läuft und erhält die Standard-Rack-App Rückgabewerte (Status , Überschriften, Körper). Meine Vermutung ist, dass Sie gehen, um Ihre Anwendung zu haben, zu modifizieren und zu sammeln und zugänglich alle seine Instanzvariablen zu machen.

In jedem Fall ist es am besten Test für Ergebnisse, nicht Implementierungsdetails. Wenn Sie sicher, dass ein Link Bearbeiten nicht sichtbar machen wollen ist, Test für das Vorhandensein des Link Bearbeiten von DOM-ID:

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

Andere Tipps

Es ist möglich, mit einem kleinen Hack. Sinatra App-Instanzen sind nicht verfügbar, da sie erstellt werden, wenn Sinatra :: Base # Aufruf aufgerufen wird. wie Alex erklärt. Dieser Hack bereitet eine Instanz voraus und lassen Sie die nächsten Anruf greift es.

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

dachte ich diese Technik, um Mock die Instanz, die den aktuellen Test in erster Linie ausgeführt wird.

Heres eine unangenehme, aber praktikable Alternative

# 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

Auf diese Weise können Sie gegen einen sinatra testen, bevor Filter und oder Zugriffsinstanzvariablen für die Basisanwendung erstellt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top