= assert-response == Description Assert-methods (sugar) and a tiny DSL to facilitate testing of rack apps with {Rack::Test}. The idea is that an error on the server side should be exposed to the tests as a real error (not hidden inside last_response.errors). +assert-response+ raises the correct error and gives us the backtrace back in our tests. Most of the time we check for the body of the response and then almost always a 404 - Not found is regarded as an error. Further we mostly want to check against Strings that are contained in the response body, while in some cases we need Regexps. So this methods and DSL makes the normal cases easier while making special cases possible. To use it in your tests: require 'rack/test' require 'assert-reponse' include Rack::Test::Methods (for usage without the inclusion of Rack::Test::Methods, see {AssertResponse::Methods} And then to test do something like this: get '/myroute' assert_response do is_html # checks content-type body 'my body' # same as 'body /my\ body/' end the same could be shorter: get '/myroute' assert_response do html 'my body' end or even: get '/myroute' assert_response_html 'my body' Predefined are the content types of html, css, js and json. But you may register your own by calling {AssertResponse.add_content_type}. Then you get all that assert_response_[your_content_type], assert_response_is_[your_content_type] and assert_response_not_found_[your_content_type] methods for granted. == Installation gem install assert-response Usually +assert_response+ checks +last_response+, but you could also pass a response Object: get '/a' a = last_response get '/b' assert_response a do # checks /a html 'body of a' end Inside the code block use the methods of {AssertResponse}. == Usage There are two ways to use assert-response: You could use the DSL or the assert_response_xxx methods. === DSL The DSL mode is handy if you want to perform several tests against the same response. You call +asser_response+ and give it a code block. All methods of the DSL are methods of {AssertResponse} so have a look there. get '/hello_world' assert_response do body 'body of hello_world' ok # same as "status 200" is_html end === assert_response_xxx methods Some of the checks could be done simpler since some assertions imply other. The code above could be simplified to get '/hello_world' assert_response_html 'body of hello_world' A call to assert_response_[method] will be forwarded to the according method of {AssertResponse}. But it checks always +last_response+, so if you need to pass the response object you will have to use the DSL. == Examples === HTML and other content lets see what the following does get '/myroute' assert_response { html 'my body' } or shorter: get '/myroute' assert_response_html 'my body' # with the cousins assert_response_css, assert_response_js and assert_response_json * It checks if +"/myroute"+ has the +Content-Type+ +"text/html"+ and the +body+ matches /my\ body/. * It also checks if +status+ of the response is +200+. * If the +status+ of the response is +500+ the original error of the rack app is raised (with original message and backtrace!) * If +status+ is +404+ an error of class {AssertResponse::Status404} is raised. === Redirects To check if "/myredirect" returns +status+ 302 and the header +Location+ matches /\/mytarget/, try get '/myredirect' assert_response do status 302 header 'Location', '/mytarget' end or shorter: get '/myredirect' assert_response_redirect '/mytarget' === Server Errors Server errors should not happen, but if they do we want them to show up as errors in our test cases. The following checks if the route +"/error"+ raises an error of class +RuntimeError+ with a message that matches +/my\ error\ message/+ get '/error' assert_response { raises RuntimeError, "my error message" } or shorter get '/error' assert_response_raises RuntimeError, "my error message" If we are not interested in the error class or message we omit them. get '/error' assert_response_raises === 404 - not found If we expect a status 404, we could do get '/not-existant' assert_response_status 404 or get '/not-existant' assert_response { not_found } or get '/not-existant' assert_response_not_found Most of the time we don't want a 404 response in our tests, so it's an error. If we test for a body of a known content-type (eg. with assert_html, assert_js and friends) it is assumed that we don't want a 404 response, so an error will be thrown if we get some. So to be able to check the body too to test a customer 404 page, we could do: get '/not-existant' assert_response do not_found header('Content-Type', 'text/html') # {AssertResponse#is_html} could not be used since it implies a status 200 body "Page could not be found" # {AssertResponse#html} could not be used since it implies a status 200 end or get '/not-existant' assert_response_not_found_html "Page could not be found" # also 'assert_not_found_js' and friends === Custom Headers get '/special' assert_response_header 'my_header', 'my header value' === Custom Content-Types get '/special' assert_response_content_type 'my/contenttype' or AssertResponse.add_content_type :my_type, 'my/contenttype' # and then get '/special' assert_response_my_type 'here the body of my type' == Contributing to assert-response * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it * Fork the project * Start a feature/bugfix branch * Commit and push until you are happy with your contribution * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally. * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it. == Copyright Copyright (c) 2011 Marc Rene Arns. See LICENSE.txt for further details.