I have a rack application (specifically a Sinatra one, but I don't think that matters) which, when running normally, happily outputs a bunch of information about the requests which are being made of it to STDOUT eg:
127.0.0.1 - - [25/Jul/2013 10:05:39] "GET /oath2/token?password=ohnoes HTTP/1.1" 404 507 0.0013
I'm trying write an extension for Rack::CommonLogger that will remove passwords from the logfile, so of course my first task is to write a test.
I have rack/test set up with rspec like so, but I can't figure out how to capture the outgoing logs so I can scan what's in them! Any ideas?
require 'my_webapp'
describe "My Webapp" do
  include Rack::Test::Methods
  def app
    @app ||= MyWebapp.new
  end
  it 'should not log the text of any GET password parameter' do
    get '/oauth2/token?password=ohnoes'
    # Not sure about this!
    log_output.should_not =~ /ohnoes/
  end
end
 
                        
You need to stub and set expectations on whatever method your custom logger is calling to write its output.
So, for example, if your custom logger writes directly to
STDERRwith a single argument, you would use:If your custom logger writes to the default logger (i.e.
env['rack.errors']) instead of STDERR, then you would stub thewritemethod of that object instead. I would have shown that example, but I can't figure out how to get a hold of the Rack environment within an RSpec test.A couple of notes on this implementation:
any_number_of_times, as inSTDERR.should_receive(:write).any_number_of_timesis deprecated in favor ofstubSTDERR.stub(:write).with(/regex/)