user681768
user681768

Reputation:

How do I configure RSpec with Sinatra to dynamically determine which Sinatra app is running before my test suite runs?

Ok so. I'm wanting to do request specs with RSpec for my Sinatra app.

I have a config.ru

# config.ru
require File.dirname(__FILE__) + '/config/boot.rb'

map 'this_route' do
  run ThisApp
end

map 'that_route' do
  run ThatApp
end

The boot.rb just uses Bundler and does additional requires for the rest of the app:

ThisApp looks like:

# lib/this_app.rb

class ThisApp < Sinatra::Base
  get '/hello' do
    'hello'
  end
end

So I'm using RSpec and I want to write request specs like:

# spec/requests/this_spec.rb
require_relative '../spec_helper'

describe "This" do
  describe "GET /this_route/hello" do
    it "should reach a page" do
      get "/hello"
        last_response.status.should be(200)
      end
    end

    it "should reach a page that says hello" do
      get "/hello"
        last_response.body.should have_content('hello')
      end
    end
  end
end

This works fine because my spec_helper.rb is setup as follows:

# spec/spec_helper.rb
ENV['RACK_ENV'] = "test"
require File.expand_path(File.dirname(__FILE__) + "/../config/boot")
require 'capybara/rspec'

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

def app
  ThisApp
end

But my problem is that I want to test "ThatApp" from my rackup file along with any amount more apps I might add later along with "ThisApp". For example if I had a second request spec file:

# spec/requests/that_spec.rb
require_relative '../spec_helper'

describe "That" do
  describe "GET /that_route/hello" do
    it "should reach a page" do
      get "/hello"
        last_response.status.should be(200)
      end
    end

    it "should reach a page that says hello" do
      get "/hello"
        last_response.body.should have_content('hello')
      end
    end
  end
end

RackTest requires the rack app I'm testing be defined in the spec_helper file with that 'app' method, and I think eventually I'm going to have to feed Capybara.app the same thing as well when doing further request specs with it.

I feel like I'm missing something and maybe there's an easy way to setup 'app' for RackTest and Capybara at runtime depending on what route and consequent rack app I'm testing in my request specs. Like a before filter in RSpec.configure maybe, but I can't think of or find how I'd access what rack app is currently loaded and try and set it there before the test suite runs.

Anyone get what I'm trying to do and can think of something? Thanks for any help.

Upvotes: 3

Views: 5997

Answers (2)

scable
scable

Reputation: 4084

Have a look at my sinatra-rspec-bundler-template. Especially at the spec files. I think that's what you are trying to achieve.

It combines two separate Sinatra apps each with it's own specs.

Upvotes: 0

Myron Marston
Myron Marston

Reputation: 21810

Define a different helper module for each sinatra app you want to test, each of which should define its own app method that returns the corresponding app. Then you can simply include MySinatraAppHelper in the appropriate example groups where you want to test the the given app.

You can also use rspec metadata to have the module included in example groups automatically.

Upvotes: 1

Related Questions