2013-07-06 22 views
14

Ich habe einige Rack-Middleware geschrieben und jetzt versuche ich es mit Rspec zu testen. Aber alle Rack-Middleware wird mit einem 'app' Argument instanziiert, das die Rails App selbst darstellt. Wie machst du das in Rspec?Testen Middleware mit Rspec

Zum Beispiel

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 

Antwort

18

brauchen nur die einfachsten Rack-App der Welt:

let(:app) { lambda {|env| [200, {'Content-Type' => 'text/plain'}, ['OK']]} } 

auch Konstruktor Ihre Middle sollte eine App als erste parame erhalten ter kein Hash so sollte es lesen:

subject { MyMiddleWare.new(app) } 

Aller Wahrscheinlichkeit nach, obwohl die Test die Middleware brauchen wird, um zu bestimmen, welche Auswirkungen auf die Anfrage hatte. Sie könnten also eine etwas anspruchsvollere Rack-App schreiben, um Ihre Middleware auszuspionieren.

und dann werden Sie wahrscheinlich Rack :: MockRequest verwenden möchten, um die Anfrage tatsächlich zu senden. Etwas wie:

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

Es gibt keinen Aufruf, hier zu unterbreiten, wie funktioniert das eigentlich? – Calin

+0

Dies ist eigentlich keine gültige Rack App. Das "Lambda" müsste ein Argument sein, um eine gültige Rack App zu sein. – branch14

+0

Aktualisiert zum Posten - Danke, @Calin. – Ritchie

0

Ich glaube, Sie Anfrage Spezifikationen simulieren eine HTTP-Anforderung (Middleware in Schienen-Middleware-Stack enthalten sein sollte) verwenden sollten. Weitere Details zu rspec request specs here.

UPD Ich glaube, ich habe genau das gefunden, was Sie brauchen, mit Test :: Unit, aber es ist einfach für RSpec neu zu schreiben: rack-ssl-enforcer

0

ich meine wie so getestet Sie

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