2012-09-07 38 views
11

Tôi đang viết một ứng dụng Sinatra gọi một số dịch vụ bên ngoài. Tôi muốn rõ ràng là thử nghiệm của tôi để tránh gọi các dịch vụ thực tế để cho rằng tại thời điểm này tôi có điều nàyTiêm phụ thuộc trong ứng dụng Sinatra

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

Và trong thử nghiệm của tôi

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 

tôi có thể nghĩ đến hai cách để tiêm này. Tôi có thể gọi một phương thức thể hiện hoặc truyền phụ thuộc thông qua hàm tạo. Dù sao kể từ khi rack dường như không cho tôi truy cập vào ví dụ ứng dụng hiện tại tôi đang tìm thấy điều này không thể.

Tôi có thể khai báo phương thức lớp cho điều này nhưng tôi muốn làm việc với các phiên bản nếu có thể. Để giữ cho khả năng có thể có tiêm khác nhau trong mỗi trường hợp và tránh tình trạng toàn cầu có thể gây hại cho các xét nghiệm khác nếu tôi quên trạng thái rollback.

Có cách nào để thực hiện việc này không?

Xin cảm ơn trước.

+1

Tôi thích ý tưởng đầu tiên của bạn (ví dụ gọi phương thức trực tiếp) và có vấn đề tương tự. Tôi cố gắng khởi tạo ứng dụng của mình theo nghĩa bình thường trong thử nghiệm, ví dụ: 'app = MyApp.new' nhưng tôi không thể gọi phương thức instance trên cá thể này. Có một cái gì đó trong Sinatra :: Base ngăn chặn các phương thức công khai? Chỉnh sửa - nếu bạn thích phương pháp này, chuỗi này có thể giúp bạn: http://stackoverflow.com/questions/12072865/calling-a-sinatra-app-instance-method-from-testcase –

Trả lời

1

Cuối cùng tôi quản lý để làm điều này với

describe "my app" do 

    def app 
    @INSTANCE 
    end 

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

    #tests here 

end 

Mặc dù tôi không đặc biệt như sử dụng mới! quá tải tại thời điểm nó hoạt động. Tôi có thể sử dụng cá thể sẽ được sử dụng với mỗi bài kiểm tra với app.whatever_method

9

Dường như có một vài tùy chọn. Bạn có thể truyền phụ thuộc vào thông qua hàm tạo hoặc sử dụng các thiết lập.

Constructor 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 

Và trong spec:

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 

Cài đặt

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 

Và trong spec:

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 
Các vấn đề liên quan