Calling a Sinatra app instance method from TestCase

后端 未结 2 1118
礼貌的吻别
礼貌的吻别 2021-01-04 06:14

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 i

2条回答
  •  花落未央
    2021-01-04 07:00

    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).

提交回复
热议问题