我已经写了一些Rack-Middleware,现在我试图用Rspec进行测试.但是所有Rack-Middleware都是用“app”参数实例化的,它代表了Rails应用程序本身.你怎么在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
@R_404_323@
您只需要世界上最简单的Rack应用程序:
let(:app) { lambda {|env| [200,{'Content-Type' => 'text/plain'},['OK']]} }
此外,您的中间件的构造函数应该会收到一个应用程序作为其第一个参数,而不是哈希值,因此应该读取:
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,['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