2012-09-07 26 views
11

私はいくつかの外部サービスを呼び出すSinatraアプリケーションを書いています。私はこのSinatraアプリケーションの依存関係の注入

class MyApp < Sinatra::Base 
    get '/my_method' do 
    @result = ExternalServiceHandler.new.do_request 
    haml :my_view 
    end 
end 

を持っており、私のテスト

describe "my app" do 
    include Rack::Test::Methods 
    def app() MyApp end 

    it "should show OK if call to external service returned OK" do 
    @external_service_handler = MiniTest::Mock.new 
    @external_service_handler.expect :do_request, "OK" 

    #Do the injection 

    get '/my_method' 
    response.html.must_include "OK" 
    end 

    it "should show KO if call to external service returned KO" do 
    @external_service_handler = MiniTest::Mock.new 
    @external_service_handler.expect :do_request, "KO" 

    #Do the injection 

    get '/my_method' 
    response.html.must_include "KO" 
    end 

end 

私はこれを注入するための2つの方法を考えることができますに明らかに私のテストは、実際のサービスを呼び出さないので、現時点で想定したいです。私はインスタンスメソッドを呼び出すか、コンストラクタを介して依存関係を渡すことができます。とにかくラックは現在のアプリケーションインスタンスにアクセスできないようですが、これは不可能です。

これはクラスメソッドを宣言できますが、可能であればインスタンスで作業することをお勧めします。各ケースで異なる注入を潜在的に可能にし、状態をロールバックすることを忘れた場合に他のテストに悪影響を与える可能性のあるグローバル状態を回避する。

これを行う方法はありますか?

ありがとうございます。

+1

私はあなたの最初のアイデア(インスタンスメソッドの呼び出しを直接)が好きで、同様の問題があります。私はテスト内で通常の意味で私のアプリを初期化しようとします。 'app = MyApp.new'ですが、このインスタンスでインスタンスメソッドを呼び出すことができません。 Sinatra :: Baseの何かがパブリックインスタンスメソッドを妨害しますか? 編集 - あなたがこのアプローチが好きなら、このスレッドはあなたを助けるかもしれません: http://stackoverflow.com/questions/12072865/calling-a-sinatra-app-instance-method-from-testcase –

答えて

1

私は最終的に私は特に新しいを使用して好きではないが、

describe "my app" do 

    def app 
    @INSTANCE 
    end 

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

    #tests here 

end 

でこれを行うために管理!それが働いているときに過負荷になります。 app.whatever_methodで各テストで使用されるインスタンスを使用できます

9

これはいくつかのオプションがあるようです。依存関係をコンストラクターに渡すか、設定を使用することができます。コンストラクタのArgs

class MyApp < Sinatra::Base 
    def initialize(app = nil, service = ExternalServiceHandler.new) 
     super(app) 
     @service = service 
    end 

    get "/my_method" do 
     @result = @service.do_request 
     haml :my_view 
    end 
end 

そしてスペックで

describe "my app" do 
    include Rack::Test::Methods 

    let(:app) { MyApp.new(service) } 
    let(:service) { double(ExternalServiceHandler) } 

    context "when the external service returns OK" do 
     it "shows OK" do 
      expect(service).to receive(:do_request).and_return("OK") 

      get '/my_method' 
      response.html.must_include "OK" 
     end 
    end 

    context "when the external service returns KO" do 
     it "shows KO" do 
      expect(service).to receive(:do_request).and_return("KO") 

      get '/my_method' 
      response.html.must_include "KO" 
     end 
    end 
end 

設定

class MyApp < Sinatra::Base 
    configure do 
     set :service, ::ExternalServiceHandler.new 
    end 

    get "/my_method" do 
     @result = settings.service.do_request 
     haml :my_view 
    end 
end 

そしてスペックで

関連する問題