1

I've modularised by classic sinatra app and moved my routes in my sinatra app into individual routes files as per https://stackoverflow.com/a/5030173/111884, however, I can't seem to get my tests working.

This is what my files look like:

./web.rb

require 'sinatra'
require 'sinatra/flash'

class MyApp < Sinatra::Application
  # ...
end

require_relative 'models/init'
require_relative 'helpers/init'
require_relative 'routes/init'

./routes/init.rb

require_relative 'main'

./routes/main.rb

# The main routes for the core of the app
class MyApp < Sinatra::Application
  get '/' do
    erb :main
  end
end

./spec/spec_helper.rb

ENV['RACK_ENV'] = 'test'
require 'minitest/autorun'
require 'rack/test'
require 'factory_girl'

# Include factories.rb file
begin
  require_relative '../test/factories.rb'
rescue NameError 
  require File.expand_path('../test/factories.rb', __FILE__)
end

# Include web.rb file
begin
  require_relative '../web'
rescue NameError 
  require File.expand_path('../web', __FILE__)
end

./spec/web_spec.rb

begin 
  require_relative 'spec_helper'
rescue NameError
  require File.expand_path('spec_helper', __FILE__)
end

include Rack::Test::Methods

def app() Sinatra::Base end

describe "Some test" do
  # ...
end

Rakefile

# Test rake tasks
require 'rake/testtask'
Rake::TestTask.new do |t|
  t.libs << "test"
  t.libs << "spec"
  t.test_files = FileList['test/factories.rb', 'test/test_*.rb', 'spec/spec_helper.rb', 'spec/**/*_spec.rb']
  t.verbose = true
end

The output of the tests is:

<h1>Not Found</h1>

It doesn't seem to be loading the ./routes/*.rb files.

I'm using Sinatra::Application, instead of Sinatra::Base, but https://stackoverflow.com/a/5030173/111884 uses it. It also references it here http://www.sinatrarb.com/extensions.html. I have tried changing it to use Sinatra::Base, but it didn't fix it.

I've also tried Sinatra tests always 404'ing and Using Cucumber With Modular Sinatra Apps, but they don't work.

Community
  • 1
  • 1
zlog
  • 3,316
  • 4
  • 42
  • 82
  • Not an answer, but attention... I tried the exact same post - and split everything up, and then took it all out - too complicated. I have switched to making all the routes in the one main app file - and each route call is only one or two lines, with the grunt work happening in all other files. Then to figure out whats happening with routes its all in one file. This file is not as big as I thought it might get. There are fewer routes than I thought I would need. I also practice using classes vs modules as much as possible so as to keep things reusable and to lower unintentional side effects. – Tom Andersen Dec 07 '11 at 01:07
  • Think I'll be doing the same thing. It is a little complicated, but I think it is worthwhile when the app grows. However, tests running is more important than separating code into files right now. – zlog Dec 07 '11 at 11:04

1 Answers1

6

I think you just need to change your app method to return your modularised application class (MyApp) rather than the Sinatra::Base class. So replace:

def app() Sinatra::Base end

in web_spec.rb, with:

def app
  MyApp
end

Rack::Test::Methods depends on the app method to tell it which class to call to process requests. In a simple non-modular Sinatra application that class is Sinatra::Base because that is the class in which the routes are applied by default. In a modular application that is the class in which you define your routes (MyApp in your case).

Steve
  • 15,606
  • 3
  • 44
  • 39
  • Oh, that was ridiculously easy! I did try this early on, but I thought it didn't work because I had some other issue with my tests. Thanks for making me try it again! – zlog Dec 12 '11 at 13:59