2017-01-11 3 views
0

Я пытаюсь получить освещение в следующих разделах кода в моей прилагаемой спецификации. Этот проект предпочитает использовать заглушки по видеомагнитофону, а внешние запросы API блокируются. Есть ли у кого-нибудь идеи о том, как подойти к этой проблеме, чтобы получить необходимый охват?Как получить покрытие при использовании спасения и повторить попытку с помощью заглушек, а не видеомагнитофона, в Rspec 3.5?

У меня есть тест сна, прокомментированный, потому что он терпит неудачу.

Код

def first_page 
    client.list_orders(created_before: created_before, 
         created_after: created_after, 
         max_results_per_page: max_results_per_page) 
    rescue Excon::Error::ServiceUnavailable => error 
    log_error(error, 'amazon_mws.errors.orders.first_page') unless (self.retries -= 1).positive? 
    add_api_delay 
    retry 
    end 

    def next_page(next_token) 
    client.list_orders_by_next_token(next_token) 
    rescue Excon::Error::ServiceUnavailable => error 
    log_error(error, 'amazon_mws.errors.orders.next_page') unless (self.retries -= 1).positive? 
    add_api_delay 
    retry 
    end 

    def add_api_delay 
    sleep(Configurations.amazon_mws['orders']['response_timer_in_seconds']) 
    end 

Spec

describe '.poll_for_order_items' do 
    context 'multiple pages' do 
     before do 
     stub_request(:any, /.*amazonservices.com.*/) 
      .with(body: /^.*(&Action=ListOrderItems&).*$/) 
      .to_return(body: next_page, status: 200, headers: { 'Content-Type': 'text/xml' }) 

     stub_request(:any, /.*amazonservices.com.*/) 
      .with(body: /^.*(&Action=ListOrderItemsByNextToken&).*$/) 
      .to_return(body: first_page, status: 200, headers: { 'Content-Type': 'text/xml' }) 
     end 

     context 'with sleep stubbed' do 
     before do 
      allow(subject).to receive(:add_api_delay).and_return(true) 
     end 

     it 'returns array collection' do 
      expect(subject.poll_for_order_items).to be_kind_of(Array) 
     end 

     it 'returns array data' do 
      expect(subject.poll_for_order_items.length).to be > 0 
     end 
     end 

     # context 'with sleep set' do 
     # it 'should call sleep' do 
     #  allow(Kernel).to receive(:sleep).and_return(1) 
     #  expect(subject).to receive(:sleep).and_return(1) 
     #  subject.poll_for_order_items 
     # end 
     # end 
    end 

    context 'single page' do 
     before(:each) do 
     stub_request(:any, /.*amazonservices.com.*/).to_return(body: first_page, status: 200, headers: { 'Content-Type': 'text/xml' }) 
     allow(subject).to receive(:add_api_delay).and_return(true) 
     end 

     it 'returns array' do 
     expect(subject.poll_for_order_items).to be_kind_of(Array) 
     end 

     it 'returns array data' do 
     expect(subject.poll_for_order_items.length).to be > 0 
     end 
    end 

    context 'collector' do 
     before(:each) do 
     stub_request(:any, /.*amazonservices.com.*/).to_return(body: first_page_single, status: 200, headers: { 'Content-Type': 'text/xml' }) 
     allow(subject).to receive(:add_api_delay).and_return(true) 
     end 

     it 'returns array when non array returned' do 
     expect(subject.poll_for_order_items).to be_kind_of(Array) 
     end 
    end 
    end 

    describe 'raises errors' do 
    context '.parse' do 
     let(:error_raised) { I18n.t('amazon_mws.errors.parse_payload') } 

     before do 
     stub_request(:any, /.*amazonservices.com.*/) 
      .with(body: /^.*(&Action=ListOrderItems&).*$/) 
      .to_return(body: {}.to_json, status: 200, headers: { 'Content-Type': 'text/xml' }) 
     end 

     it 'raises error' do 
     expect { subject.new } .to raise_error(StandardError) 
     end 
    end 

    context '.first_page' do 
     let(:error_raised) { I18n.t('amazon_mws.errors.order_items.first_page') } 

     before do 
     allow(MWS).to receive_message_chain(:orders, :list_order_items).and_raise(error_raised) 
     end 

     it 'raises error on first listing page' do 
     expect { subject.new } .to raise_error(StandardError) 
     end 
    end 

    context '.next_page' do 
     let(:error_raised) { I18n.t('amazon_mws.errors.order_items.next_page') } 

     before do 
     stub_request(:any, /.*amazonservices.com.*/) 
      .with(body: /^.*(&Action=ListOrderItems&).*$/) 
      .to_return(body: next_page, status: 200, headers: { 'Content-Type': 'text/xml' }) 

     stub_request(:any, /.*amazonservices.com.*/) 
      .with(body: /^.*(&Action=ListOrderItemsByNextToken&).*$/) 
      .and_raise(error_raised) 

     allow(subject).to receive(:add_api_delay).and_return(true) 
     end 

     it 'raises error on nexst listing page' do 
     expect { subject.poll_for_order_items } .to raise_error(StandardError) 
     end 
    end 
    end 

Покрытие Отчет enter image description here

ответ

0

После исследования и вдохновение из @wobh выше, я придумал следующее ...

describe '.poll_for_order_items' do 
    context 'multiple pages' do 
     before do 
     stub_request(:any, /.*amazonservices.com.*/) 
      .with(body: /^.*(&Action=ListOrderItems&).*$/) 
      .to_return(body: next_page, status: 200, headers: { 'Content-Type': 'text/xml' }) 

     stub_request(:any, /.*amazonservices.com.*/) 
      .with(body: /^.*(&Action=ListOrderItemsByNextToken&).*$/) 
      .to_return(body: first_page, status: 200, headers: { 'Content-Type': 'text/xml' }) 
     end 

     context 'with sleep stubbed' do 
     before do 
      allow(subject).to receive(:add_api_delay).and_return(true) 
     end 

     it 'returns array collection' do 
      expect(subject.poll_for_order_items).to be_kind_of(Array) 
     end 

     it 'returns array data' do 
      expect(subject.poll_for_order_items.length).to be > 0 
     end 
     end 
    end 

    context 'single page' do 
     before(:each) do 
     stub_request(:any, /.*amazonservices.com.*/).to_return(body: first_page, status: 200, headers: { 'Content-Type': 'text/xml' }) 
     allow(subject).to receive(:add_api_delay).and_return(true) 
     end 

     it 'returns array' do 
     expect(subject.poll_for_order_items).to be_kind_of(Array) 
     end 

     it 'returns array data' do 
     expect(subject.poll_for_order_items.length).to be > 0 
     end 
    end 

    context 'collector' do 
     before(:each) do 
     stub_request(:any, /.*amazonservices.com.*/).to_return(body: first_page_single, status: 200, headers: { 'Content-Type': 'text/xml' }) 
     allow(subject).to receive(:add_api_delay).and_return(true) 
     end 

     it 'returns array when non array returned' do 
     expect(subject.poll_for_order_items).to be_kind_of(Array) 
     end 
    end 
    end 

    describe 'raises errors' do 
    context '.parse' do 
     let(:error_raised) { I18n.t('amazon_mws.errors.parse_payload', error: 'TEST') } 

     before do 
     stub_request(:any, /.*amazonservices.com.*/) 
      .with(body: /^.*(&Action=ListOrderItems&).*$/) 
      .to_return(body: {}.to_json, status: 200, headers: { 'Content-Type': 'text/xml' }) 
     end 

     it 'raises error' do 
     expect { subject.poll_for_order_items } .to raise_error(StandardError) 
     end 

     it 'raises correct error message' do 
     expect { subject.poll_for_order_items } .to raise_error(/payload/) 
     end 
    end 

    context '.first_page' do 
     let(:error_raised) { I18n.t('amazon_mws.errors.order_items.first_page', error: 'TEST') } 

     before do 
     stub_request(:any, /.*amazonservices.com.*/) 
      .with(body: /^.*(&Action=ListOrderItems&).*$/) 
      .to_raise(Excon::Error::ServiceUnavailable) 
     subject.instance_variable_set(:@retry_limit, 1) 
     allow(subject).to receive(:add_api_delay).and_return(true) 
     end 

     it 'raises error on first listing page' do 
     expect { subject.poll_for_order_items } .to raise_error(StandardError) 
     end 

     it 'raises correct error message' do 
     expect { subject.poll_for_order_items } .to raise_error(/order item first/) 
     end 
    end 

    context '.next_page' do 
     let(:error_raised) { I18n.t('amazon_mws.errors.order_items.next_page', error: 'TEST') } 

     before do 
     stub_request(:any, /.*amazonservices.com.*/) 
      .with(body: /^.*(&Action=ListOrderItems&).*$/) 
      .to_return(body: next_page, status: 200, headers: { 'Content-Type': 'text/xml' }) 

     stub_request(:any, /.*amazonservices.com.*/) 
      .with(body: /^.*(&Action=ListOrderItemsByNextToken&).*$/) 
      .to_raise(Excon::Error::ServiceUnavailable) 
     subject.instance_variable_set(:@retry_limit, 1) 
     allow(subject).to receive(:add_api_delay).and_return(true) 
     end 

     it 'raises error on next listing page' do 
     expect { subject.poll_for_order_items } .to raise_error(StandardError) 
     end 

     it 'raises correct error message' do 
     expect { subject.poll_for_order_items } .to raise_error(/order item next/) 
     end 
    end 

    context '.add_api_delay' do 
     before do 
     stub_request(:any, /.*amazonservices.com.*/) 
      .with(body: /^.*(&Action=ListOrderItems&).*$/) 
      .to_raise(Excon::Error::ServiceUnavailable) 

     subject.instance_variable_set(:@retries, 2) 
     subject.instance_variable_set(:@retry_limit, 1) 
     subject.instance_variable_set(:@retry_delay, 1) 
     end 

     it 'sleeps retry api calls' do 
     allow(Kernel).to receive(:sleep).and_return(1) 
     expect(subject).to receive(:sleep).and_return(1) 
     expect { subject.poll_for_order_items } .to raise_error(StandardError) 
     end 
    end 
    end 

это вылилось в 100% -ном охвате!

0

Я только вижу, что вы ждете его, чтобы поднять эту ошибку. Если это тайм-аут, тогда он должен позвонить по телефону log_error и add_api_delay хотя бы один раз. Поскольку это в основном побочные эффекты, вам просто нужно проверить, что они вызваны в этом случае, и отчет о покрытии должен знать об этом.

Попробуйте добавить ожидания, как: expect(subject).to have_received(:log_error).at_least(:once)

EDIT: Если говорить об этом вне группы, и мы узнали, большая часть проблемы покрытия может быть решена, убедившись, что ошибка поднимается.

before do stub_request(:any, /.*amazonservices.com.*/) .with(body: /^.*(&Action=ListOrders&).*$/) .to_raise(Excon::Error::ServiceUnavailable) end

Смежные вопросы