2013-08-11 1 views
3

У меня есть следующий метод, который отвечает за запрос URL-адреса и возвращает его Nokogiri::HTML. Этот метод проверяет, определен ли прокси-сервер, и если он это сделает, он будет звонить OpenURIopen с опциями прокси или без них.Как проверить этот метод?

Реализация

require 'open-uri' 
require 'nokogiri' 

class MyClass 
    attr_accessor :proxy 

    # .... 

    def self.page_content(url) 
    if MyClass.proxy 
     proxy_uri = URI.parse(MyClass.proxy) 
     Nokogiri::HTML(open(url, :proxy => proxy_uri)) # open provided by OpenURI 
    else 
     Nokogiri::HTML(open(url)) # open provided by OpenURI 
    end 
    end 
end 

Я понятия не имею, как я должен писать тесты, доказывающие следующее:

  1. Когда прокси определен запрос OpenURI делает на самом деле использует прокси-данные
  2. Когда прокси-сервер не определен, выполняется обычное не-прокси-соединение

Вот что я придумал для начала тестов.

describe MyClass, :vcr do 

    describe '.proxy' do 
    it { should respond_to(:proxy) } 
    end 

    describe '.page_content' do 
    let(:url) { "https://google.com/" } 
    let(:page_content) { subject.page_content(url) } 

    it 'returns a Nokogiri::HTML::Document' do 
     page_content.should be_a(Nokogiri::HTML::Document) 
    end 

    # How do i test this method actually uses a proxy when it's set vs not set? 
    context 'when using a proxy' do 
     # ??? 
     xit 'should set open-uri proxy properties' do 
     end 
    end 

    context 'when not using a proxy' do 
     # ??? 
     xit 'should not set open-uri proxy properties' do 
     end 
    end 

    end 

end 
+0

Что означает 'open' в вашей реализации? –

+0

@PeterAlfvin 'open' предоставляется OpenURI. Я прокомментирую код, чтобы это было четко указано. – CharlesHorse

+0

Вы действительно хотите открыть URI и вызвать Nokogiri как часть вашего теста или вы хотите просто убедиться, что вы делаете эти вызовы (например, с помощью заглушек)? –

ответ

2

Прежде всего, вам нужно организовать для метода proxy для возврата прокси в одном тесте, а не в другом. Если для прокси-сервера существует метод «setter», вы можете его использовать, иначе вы можете заглушить метод proxy.

Затем, как минимум, вы хотите установить ожидание на open, что он будет вызываться с опцией :proxy или без нее, в зависимости от того, какой тест он есть. Кроме того, у вас есть выбор: заглушить и установить ожидания для различных других вызовов, участвующих в методе, включая URI.parse и Nokogiri::HTML.

См. https://github.com/rspec/rspec-mocks для получения информации об установлении двойного действия теста и определении ожиданий. Обратите внимание, в частности, на параметр and_call_original, если вы хотите использовать частичный подход к тиснению.

Обновление: вот несколько кодов, которые помогут вам начать работу. Это работает для не-прокси-метода. Я оставил дело прокси для вас. Обратите также внимание на то, что в этом случае используется метод «частичного опускания», где вы все равно вызываете внешние драгоценные камни.

require 'spec_helper' 

describe MyClass do 

    describe '.proxy' do   # NOTE: This test succeeds because of attr_accessor, but you're calling a MyClass.proxy (a class method) within your page_content method 
    it { should respond_to(:proxy) } 
    end 

    describe '.page_content' do 
    let(:url) { "https://google.com/" } 
    let(:page_content) { MyClass.page_content(url) } # NOTE: Changed to invoke class method 

    context 'when not using a proxy' do 

     before {allow(MyClass).to receive(:proxy).and_return(false)} # Stubbed for no-proxy case 

     it 'returns a Nokogiri::HTML::Document' do 
     page_content.should be_a(Nokogiri::HTML::Document) 
     end 

     it 'should not set open-uri proxy properties' do 
     expect(MyClass).to receive(:open).with(url).and_call_original # Stubbing open is tricky, see note afterwards 
     page_content 
     end 
    end 
     # How do i test this method actually uses a proxy when it's set vs not set? 
    context 'when using a proxy' do 
     # ??? 
     xit 'should set open-uri proxy properties' do 
     end 
    end 

    end 

end 

Обрушение open сложно. См. How to rspec mock open-uri? для объяснения.

+0

Я обновил свой вопрос, чтобы показать, что есть 'attr_accessor' для' proxy'. Ваш первый абзац имеет смысл; Спасибо. То, что вы сказали об использовании mocks и 'and_call_original', не имеет смысла, к сожалению. Я действительно прочитал документацию и снял книгу rspec, но у меня возникли проблемы с пониманием того, что издеваются над объектами и хотелось бы увидеть код, если это возможно. Спасибо! – CharlesHorse

+0

'attr_accessor' дает вам сеттеры и getters для * переменных экземпляра *. Вы ссылаетесь на «прокси» с помощью метода класса с тем же именем. –

+0

Вы также определили 'page_content' как' subject.page_content (...) ', но' subject' неявно является новым * экземпляром * MyClass' и не существует метода экземпляра 'page_content'. В общем, если вы начнете выполнять свою спецификацию, RSpec скажет вам, что вы ошиблись, и если вы застряли, вы можете получить помощь здесь. –