2013-07-06 4 views
14

저는 Rack-Middleware를 작성했고 Rspec으로 테스트하려고합니다. 그러나 모든 랙 미들웨어는 Rails 앱 자체를 나타내는 'app'인수로 인스턴스화됩니다. 당신은 Rspec에서 이것을 어떻게 조롱합니까? 예를 들어 Rspec으로 미들웨어 테스트하기

,

describe MyMiddleWare do 
    let(:app) { # How do I mock a Rails app object here? } 
    subject { MyMiddleWare.new(app: app) } 

    it 'should blah blah blah' do 
     # a bunch of tests go here 
    end 
end 

답변

18

당신을 같은 내 테스트 세계에서 가장 간단한 랙 앱이 필요합니다.

또한 미들웨어의 생성자는 첫 번째 매개 변수로 앱을 받아야합니다. TER 해시 읽어야하지 않도록 모든 가능성에

subject { MyMiddleWare.new(app) } 

을하지만, 테스트는 미들웨어가 요청에 미친 어떤 영향을 결정해야 할 것이다. 따라서 미들웨어를 감시하기 위해 좀 더 정교한 랙 응용 프로그램을 작성할 수 있습니다.

class MockRackApp 

    attr_reader :request_body 

    def initialize 
    @request_headers = {} 
    end 

    def call(env) 
    @env = env 
    @request_body = env['rack.input'].read 
    [200, {'Content-Type' => 'text/plain'}, ['OK']] 
    end 

    def [](key) 
    @env[key] 
    end 

end 

그런 다음 실제로 요청을 보내려면 Rack :: MockRequest를 사용하는 것이 좋습니다. 예 :

describe MyMiddleWare do 

    let(:app) { MockRackApp.new } 
    subject { described_class.new(app) } 

    context "when called with a POST request" do 
    let(:request) { Rack::MockRequest.new(subject) } 
    before(:each) do 
     request.post("/some/path", input: post_data, 'CONTENT_TYPE' => 'text/plain') 
    end 

    context "with some particular data" do 
     let(:post_data) { "String or IO post data" } 

     it "passes the request through unchanged" do 
     expect(app['CONTENT_TYPE']).to eq('text/plain') 
     expect(app['CONTENT_LENGTH'].to_i).to eq(post_data.length) 
     expect(app.request_body).to eq(post_data) 
     end 
    end 
    end 
end 
+0

여기에 제목이 필요하지 않습니다. 실제로 어떻게 작동합니까? – Calin

+0

이것은 실제로 유효한 랙 앱이 아닙니다. 'lambda '는 유효한 Rack 앱이되기 위해 논쟁을해야 할 것입니다. – branch14

+0

제목에 게시하도록 업데이트되었습니다. - 감사합니다, @ Calin. – Ritchie

0

나는 (당신의 미들웨어가 레일 미들웨어 스택에 포함되어야한다)는 HTTP 요청을 시뮬레이션 요구 사양을 사용해야합니다 생각합니다. rspec 요청 사양에 대한 자세한 내용은 here을 참조하십시오.

UPD 나는 당신이 테스트 :: 단위로, 필요 정확히 발견했다고 생각하지만, RSpec에 대한 재 작성을 쉽게 : rack-ssl-enforcer

0

내가 그렇게

describe Support::CharConverter do 

    let(:env_hash) do 
    { 
     "HTTP_REFERER" => "", 
     "PATH_INFO" => "foo", 
     "QUERY_STRING" => "bar", 
     "REQUEST_PATH" => "is", 
     "REQUEST_URI" => "here", 
    } 
    end 

    subject do 
    Support::CharConverter.new(env_hash) 
    end 

    context 'sanitize_env' do 

    it 'should keep key values the same if nothing to sanitize' do 
     sanitized_hash = subject.sanitize_env(env_hash) 
     # k = env_hash.keys[5] 
     # v = env_hash.values[5] 
     env_hash.each do |k, v| 
     sanitized_hash[k].encoding.name.should eq("US-ASCII") 
     sanitized_hash[k].should eq(v) 
     sanitized_hash[k].valid_encoding?.should eq(true) 
     end 
    end 
    end 
end 
관련 문제