Calling a Sinatra App Instance Method from Testcase

Calling a Sinatra app instance method from TestCase

Sinatra aliases the new method to new! before redefining it, so the simplest solution is to use that instead:

def app
MyApp.new!
end

Of course I only noticed that after I’d come up with the following, which I’ll leave in as it could be useful/informative.


A possible way to get round Sinatra redefining the new method and returning a complete Rack app a get hold of an instance your actual base class is to do what the “real” new method does yourself:

def app
a = MyApp.allocate
a.send :initialize
a
end

This is a bit of a hack, but it might be useful for testing.

Another technique would be to “walk” the middleware stack until you got to your class. The following is a little fragile, as it depends on all the middleware involved to use the name @app to refer to the next app in the stack, but this is fairly common.

def app
a = MyApp.new
while a.class != MyApp
a = a.instance_variable_get(:@app)
end
a
end

That won’t work on the yet to be released Sinatra 1.4 though (at least not on the current master, which is commit 41840746e866e8e8e9a0eaafc53d8b9fe6615b12), as new now returns a Wrapper class and the loop never ends. In this case you can grab the base class directly from the @instance variable:

def app
MyApp.new.instance_variable_get :@instance
end

(note this last technique may well change before the final 1.4 release).

Injecting dependencies in Sinatra app

I finally managed to do this with

describe "my app" do

def app
@INSTANCE
end

before do
@INSTANCE ||= MyApp.new!
end

#tests here

end

Although I don't particularly like using the new! overloading at the moment it's working. I can use the instance that will be used with each test with app.whatever_method

Testing controller instance variables with Rack::Test and Sinatra

Unfortunately I don't think this is possible without modifying Rack::Test. When you make a request during application testing, Rack::Test does the following:

  1. adds the request to a list of recent requests
  2. creates a new instance of your application and invokes its call method
  3. adds your application's response to a list of recent responses

It's easy to access the last_request and last_response, but unfortunately no information is saved about the state of your application while it's running.

If you're interested in hacking together a Rack::Test patch to do this, start by looking at rack-test/lib/rack/mock_session.rb on line 30. This is where Rack::Test runs your application and receives the standard Rack app return values (status, headers, body). My guess is that you're going to have to modify your application as well, to collect and make accessible all of its instance variables.

In any case, it's best to test for results, not implementation details. If you want to make sure an edit link is not visible, test for the presence of the edit link by DOM id:

assert last_response.body.match(/<a href="..." id="...">/)

Sinatra app executes during load instead of after run method issued

Okay, I get it. I put the code in a class, but not it a method. Load or require both run open code like this. I need to wrap it in methods, and execute the methods, to do what I want to do.

Sinatra examples, which I followed, don't make this clear and simply avoid the topic. Many are so simple it doesn't make a difference, and some are just coded within the config.ru. I am coming from Rails and, while I knew this from Rails, it didn't make much of a difference since the vast majority of the code already exists in methods.

Forbidden message is shown when I access a Sinatra app on AppFog

This is an easy fix, try adding this:

set :protection, :except => :ip_spoofing

We are patching our nginx soon to fix this issue, but this work around will help for now.

Return strings separated by line break in Rack application

Since a <br> tag doesn't seem to work for you, try this:

get '/page123' do
content_type 'text/plain'
"string1\nstring2"
end


Related Topics



Leave a reply



Submit