Calling a Sinatra app instance method from TestCase
rack, ruby, sinatra
Solution
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).
Problem
I have an util method into a Sinatra application and I would like to tested from my `TestCase`. The problem is that I don't know how to invoke it, if I just use `app.util_method` I have the error `NameError: undefined local variable or method 'util_method' for #<Sinatra::ExtendedRack:0x007fc0c43305b8>` my_app.rb: ``` class MyApp < Sinatra::Base # [...] routes methods # utils methods def util_method return "hi" end end ``` my_app_test.rb: ``` require "my_app.rb" require "test/unit" require "rack/test" class MyAppTest < Test::Unit::TestCase include Rack::Test::Methods def app MyApp.new end # [...] routes methods tests def test_util_method assert_equal( "hi", app.util_method ) end end ```