8

ユーザーがログインしているかどうかに応じて、ページを読み取り専用または編集可能として提供するSinatraアプリがあります。

コントローラは、@can_edit編集リンクを表示/非表示にするためにビューによって使用される変数を設定します。@can_editテストでの値をテストするにはどうすればよいですか?Rack::Testの下にあるコントローラーの現在のインスタンスを取得する方法がわかりません。

class_evalコントローラでメソッドをスタブ化するために使用しますが、編集リンクをlogged_in?チェックして、設定されているかどうかを確認する必要があります。last_response.body@can_edit

@can_editの値を直接テストするにはどうすればよいですか?

4

3 に答える 3

8

残念ながら、Rack::Test を変更しない限り、これは不可能だと思います。アプリケーションのテスト中にリクエストを行うと、Rack::Test は次のことを行います。

  1. 最近のリクエストのリストにリクエストを追加します
  2. アプリケーションの新しいインスタンスを作成し、そのcallメソッドを呼び出します
  3. アプリケーションの応答を最近の応答のリストに追加します

last_requestおよびに簡単にアクセスできますlast_responseが、残念ながら、実行中のアプリケーションの状態に関する情報は保存されません。

これを行うために Rack::Test パッチを一緒にハックすることに興味がある場合は、rack-test/lib/rack/mock_session.rb30 行目から始めてください。これは、Rack::Test がアプリケーションを実行し、標準の Rack アプリの戻り値 (ステータス、ヘッダー、本文) を受け取る場所です。 )。私の推測では、すべてのインスタンス変数を収集してアクセスできるようにするために、アプリケーションも変更する必要があると思います。

いずれにせよ、実装の詳細ではなく、結果をテストすることをお勧めします。編集リンクが表示されていないことを確認したい場合は、DOM ID で編集リンクの存在をテストします。

assert last_response.body.match(/<a href="..." id="...">/)
于 2009-12-18T16:38:11.820 に答える
4

少しのハックで可能です。Sinatra アプリのインスタンスは、Sinatra::Base#call が呼び出されたときに作成されるため、使用できません。アレックスが説明したように。このハックは、事前にインスタンスを準備し、次の呼び出しでそれを取得できるようにします。

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

最初に、現在のテストを実行するインスタンスをモックするこの手法を考え出しました。

于 2011-12-27T12:08:30.683 に答える
0

これは厄介だが実行可能な代替手段です

# 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

これにより、フィルタの前にシナトラに対してテストしたり、ベース アプリケーション用に作成されたインスタンス変数にアクセスしたりできます。

于 2016-02-24T21:36:14.817 に答える