2010-08-23 3 views
2

Я тестирую некоторые библиотеки javascript, которые я создал, используя ruby's harmony. Все работает отлично, за исключением вызовов AJAX - есть ли у кого-нибудь идеи, как это достичь?Асинхронные модульные тесты в Ruby

Мой код выглядит примерно так (я использую RightJS):

my.js

function makerequest(argument) { 
    new Xhr('http://mysite.com/some/jsonp'),{ 
     jsonp: true, 
     params: {something: argument}, 
     onSuccess: function() { 
      // Calls a function defined outside my library 
      parse_response(this.json) 
     } 
    }).send() 
} 

test_makerequest.rb

require 'rubygems' 
require 'harmony' 
require 'test/unit' 
require 'shoulda' 

class RequestTest < Test::Unit::TestCase 
    context "The requesty thing" do 
     setup do 
      @page = Harmony::Page.new 
      @page.load(File.expand_path('js/my.js')) 
     end 

     should "get stuff from mysite.com" do 
      # Here I need to define a 'parse_response' which this 
      # should section will wait for and then do an 'assert' 
      # on the results. 
      results = callback_to_get_results_from__make_request 
      @page.execute('make_request("an argument")') 
      assert results == {'foo' => 'bar'} 
     end 
    end 
end 

Так что да, мой вопрос в том, как я должен назначить results выше, чтобы я мог получить res ell асинхронного обратного вызова?

ответ

0

Асинхронные вызовы, как правило, проблематичны при тестировании модулей JS. Я решил это в прошлом, сделав вызовы XHR эффективно синхронными, заблокировав основной поток до тех пор, пока вызов XHR не завершится успешно. Как это сделать, зависит от вашей структуры, и я не знаком с Harmony и RightJS. Однако логика будет выглядеть примерно так:

  1. Переопределите метод XHR так, чтобы он поддерживал блокировку/мьютексы. Замок может быть простым булевым. Когда какой-либо XHR находится в процессе, блокировка будет true, когда XHR не будет работать, блокировка будет false.
  2. В своем тесте перед выполнением вашего утверждения добавьте цикл, который выполняет ваш XHR, а затем ждет, пока блокировка не исчезнет.
  3. Как только петля закончится, вы убедитесь, что XHR завершен, и вы можете выполнить свое утверждение.

Цель этого подхода заключается в том, чтобы избежать изменения кода, что приведет к аннулированию ваших тестов. К сожалению, это также означает, что вы не можете проверить значение возвращаемого значения, но я думаю, что это будет предостережением любой стратегии, которая не изменяет ваш код.

Другим подходом было бы фактически выполнить ваши тесты асинхронно - т.е. присоедините свое утверждение к обратному вызову onSuccess с помощью AOP. Тем не менее, многие комплекты тестов не очень хорошо сочетаются с асинхронными тестами, поскольку настройка одного теста может начинаться до отрыва предыдущего теста (т. Е. Потому что предыдущий тест все еще ожидает возврата асинхронного вызова).

Одним из последних подходов было бы издеваться над всеми асинхронными вызовами. То есть. просто переопределите XHR и попросите свой тест утверждать, что он был вызван с правильными аргументами. Я мог бы одобрить этот подход, если у меня есть интеграционные тесты, которые проходят через весь стек асинхронизации.

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