Sinatra Beyond Basics : Implement Post Driven by Tests


To implement posting to a URL driven by tests.


Step 1

Add the next test:

  it 'greets by name' do
    post '/', { 'name' => 'Bugs Bunny' }

    expect(last_response.body).to eq("Hello Bugs Bunny")  

so that your hello_spec.rb now looks like this:

require 'spec_helper'
require 'rack/test'
require_relative '../hello'

RSpec.describe 'hello app' do
  include Rack::Test::Methods

  def app

  it 'says hi' do
    get '/'

    expect(last_response).to be_ok

  it 'greets by name' do
    post '/', { 'name' => 'Bugs Bunny' }

    expect(last_response.body).to eq("Hello Bugs Bunny")  

The app method defines the active application for this test.

Step 2

Run the test.

$rspec spec/hello_spec.rb 
hello app
  says hi
  greets by name (FAILED - 1)


  1) hello app greets by name
     Failure/Error: expect(last_response.body).to eq("Hello Bugs Bunny")

       expected: "Hello Bugs Bunny"
            got: "<!DOCTYPE html>\n<html>\n<head>\n  <style type=\"text/css\">\n  body { text-align:center;font-family:helvetica,arial;font-size:22px;\n    color:#888;margin:20px}\n  #c {margin:0 auto;width:500px;text-align:left}\n  </style>\n</head>\n<body>\n  <h2>Sinatra doesn&rsquo;t know this ditty.</h2>\n  <img src=''>\n  <div id=\"c\">\n    Try this:\n    <pre>post &#x27;&#x2F;&#x27; do\n  &quot;Hello World&quot;\nend\n</pre>\n  </div>\n</body>\n</html>\n"

       (compared using ==)

       @@ -1,2 +1,22 @@
       -Hello Bugs Bunny
       +<!DOCTYPE html>
       +  <style type="text/css">
       +  body { text-align:center;font-family:helvetica,arial;font-size:22px;
       +    color:#888;margin:20px}
       +  #c {margin:0 auto;width:500px;text-align:left}
       +  </style>
       +  <h2>Sinatra doesn&rsquo;t know this ditty.</h2>
       +  <img src=''>
       +  <div id="c">
       +    Try this:
       +    <pre>post &#x27;&#x2F;&#x27; do
       +  &quot;Hello World&quot;
       +  </div>

     # ./spec/hello_spec.rb:21:in `block (2 levels) in <top (required)>'

Finished in 0.03022 seconds (files took 0.15834 seconds to load)
2 examples, 1 failure

Failed examples:

rspec ./spec/hello_spec.rb:18 # hello app greets by name

Step 3

Implement the post method :

require 'sinatra'

get '/' do

post '/' do
  "Hello #{params[:name]}"

Step 4

Run the test.

$rspec spec/hello_spec.rb 
hello app
  says hi
  greets by name

Finished in 0.02899 seconds (files took 0.15828 seconds to load)
2 examples, 0 failures

Step 5

Run the application.

$ruby hello.rb
[2015-04-15 16:59:47] INFO  WEBrick 1.3.1
[2015-04-15 16:59:47] INFO  ruby 2.2.1 (2015-02-26) [x86_64-darwin11.0]
== Sinatra (v1.4.6) has taken the stage on 4567 for development with backup from WEBrick
[2015-04-15 16:59:47] INFO  WEBrick::HTTPServer#start: pid=86461 port=4567

Step 6

Browse to http://localhost:4567. You will see hello.

Step 7

Since we don't have a view to submit the form values, we can use curl command to simulate a form post:

$curl --data "name=Bugs" http://localhost:4567

You can see the output: Hello Bugs in the terminal.

Step 8

Let's cleanup. Move the require 'rack/test' from the test file to the top of the spec_helper.rb file.

Delete the line : include Rack::Test::Methods from the test file and change the spec_helper.rb to include it as follows:

RSpec.configure do |config|
  config.include Rack::Test::Methods


Run the tests.

$rspec spec/hello_spec.rb  

It will pass.

Step 9

Automatically reload changes without server restart.

gem install shotgun

Step 10

shotgun hello.rb

Install Rest Client Chrome plugin to use various verbs to play with the server code.


In this article, we implemented the posting to an url driven by tests.

Related Articles

Ace the Technical Interview

  • Easily find the gaps in your knowledge
  • Get customized lessons based on where you are
  • Take consistent action everyday
  • Builtin accountability to keep you on track
  • You will solve bigger problems over time
  • Get the job of your dreams

Take the 30 Day Coding Skills Challenge

Gain confidence to attend the interview

No spam ever. Unsubscribe anytime.