문제

사용자가 로그인한지에 따라 페이지를 읽기 전용 또는 편집 가능한 Sinatra 앱이 있습니다.

컨트롤러는 변수를 설정합니다 @can_edit, 이는 링크 편집을 숨기기 위해보기에 사용됩니다. 어떻게 테스트 할 수 있습니까? @can_edit내 테스트에서의 가치? Rack :: Test에서 컨트롤러의 현재 인스턴스를 얻는 방법을 모르겠습니다.

나는 사용한다 class_eval 스터브 logged_in? 컨트롤러의 방법이지만 확인에 의지해야합니다. last_response.body 내 편집 링크가 @can_edit 설정되었는지 여부.

값을 어떻게 테스트 할 수 있습니까? @can_edit 곧장?

도움이 되었습니까?

해결책

불행히도 나는 이것이 랙 :: 테스트를 수정하지 않고는 가능하다고 생각하지 않습니다. 응용 프로그램 테스트 중에 요청을 할 때 Rack :: Test는 다음을 수행합니다.

  1. 최근 요청 목록에 요청을 추가합니다
  2. 신청서의 새 인스턴스를 작성하고 해당 call 방법
  3. 최근 응답 목록에 응용 프로그램의 응답을 추가합니다.

액세스하기 쉽습니다 last_request 그리고 last_response, 그러나 불행히도 응용 프로그램이 실행중인 상태에 대한 정보는 저장되지 않습니다.

랙을 해킹하는 데 관심이 있다면 :: 테스트 패치를 수행하십시오. rack-test/lib/rack/mock_session.rb 30 행에서 랙 :: 테스트가 응용 프로그램을 실행하고 표준 랙 앱 리턴 값 (상태, 헤더, 본문)을 수신합니다. 내 생각에 모든 인스턴스 변수를 수집하고 액세스 할 수 있도록 응용 프로그램을 수정해야 할 것입니다.

어쨌든 구현 세부 사항이 아닌 결과를 테스트하는 것이 가장 좋습니다. 편집 링크가 표시되지 않으려면 dom id의 편집 링크가 있는지 테스트하십시오.

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

다른 팁

약간의 해킹으로 가능합니다. Sinatra App의 인스턴스는 Sinatra :: Base#호출이 호출 될 때 생성되기 때문에 사용할 수 없습니다. 알렉스가 설명했듯이. 이 해킹은 미리 인스턴스를 준비하고 다음 호출이이를 가져 가게합니다.

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

나는이 기술을 알아 냈다 현재 테스트를 실행하는 인스턴스를 조롱하십시오 처음에.

그녀는 불쾌하지만 실행 가능한 대안입니다

# 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

이를 통해 필터 전에 Sinatra에 대해 테스트하거나 기본 애플리케이션을 위해 생성 된 인스턴스 변수에 액세스 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top