2012-09-07 13 views
11

में निर्भरता इंजेक्शन इंजेक्शन मैं एक सिनात्रा ऐप लिख रहा हूं जो कुछ बाहरी सेवाओं को कॉल करता है। मैं स्पष्ट रूप से मेरे परीक्षण वास्तविक सेवाओं बुला से बचने इतना समय लगता है करना चाहते हैं मैं इससिनात्रा ऐप

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 

मैं इस इंजेक्षन करने के दो तरीके के बारे में सोच सकते हैं। मैं एक उदाहरण विधि या कन्स्ट्रक्टर के माध्यम से निर्भरता पारित कर सकते हैं। वैसे भी जब रैक मुझे वर्तमान अनुप्रयोग उदाहरण तक पहुंच नहीं देता है, तो मुझे यह असंभव लगता है।

मैं इसके लिए एक क्लास विधि घोषित कर सकता हूं लेकिन यदि संभव हो तो मैं उदाहरणों के साथ काम करना पसंद करूंगा। प्रत्येक मामले में अलग-अलग इंजेक्शन होने और वैश्विक स्थिति से परहेज करने के लिए संभावित रूप से संभव रखने के लिए यदि मैं रोलबैक स्थिति भूल जाता हूं तो अन्य परीक्षणों को नुकसान पहुंचा सकता है।

क्या इसे पूरा करने का कोई तरीका है?

अग्रिम धन्यवाद।

+1

मुझे आपका पहला विचार पसंद है (उदाहरण विधि कॉल सीधे) और एक समान समस्या है। मैं अपने ऐप को सामान्य ज्ञान में परीक्षण के भीतर शुरू करने का प्रयास करता हूं, उदा। 'app = MyApp.new' लेकिन मैं इस उदाहरण पर उदाहरण विधियों को कॉल करने में असमर्थ हूं। क्या सिनात्रा :: बेस में कुछ सार्वजनिक उदाहरण विधियों को रोकता है? संपादित करें - अगर आपको यह दृष्टिकोण पसंद है तो यह धागा आपकी मदद कर सकता है: 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 

हालांकि मैं ऐसा विशेष रूप से नहीं नए का उपयोग कर की तरह! इस समय काम कर रहा है जब यह काम कर रहा है। मैं उस उदाहरण का उपयोग कर सकता हूं जिसका उपयोग प्रत्येक परीक्षण के साथ ऐप के साथ किया जाएगा। 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 

और कल्पना में:

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

    let(:app) { MyApp.new } 
    let(:service) { double(ExternalServiceHandler) } 
    before do 
     MyApp.set :service, service 
    end 

    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