2

我正在测试我使用 ruby​​ 的Harmony构建的一些 javascript 库。除了 AJAX 调用外,一切都运行良好——有人知道如何实现这一点吗?

我的代码看起来像这样(我正在使用RightJS):

我的.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_makerrequest.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在上面进行分配,以便我可以获得异步回调的结果?

4

1 回答 1

0

JS 单元测试中的异步调用通常会出现问题。过去,我通过阻塞主线程直到 XHR 调用成功,使 XHR 调用有效地同步来解决它。如何做到这一点取决于你的框架,我不熟悉 Harmony 和 RightJS。但是,逻辑看起来像这样:

  1. 覆盖您的 XHR 方法,以便它维护一个锁/互斥锁。锁可以是一个简单的布尔值。当任何 XHR 正在处理时,锁将为true,当没有 XHR 正在处理时,锁将为false
  2. 在你的测试中,在你运行你的断言之前,添加一个循环来执行你的 XHR,然后等待直到锁被清除。
  3. 循环完成后,您将确定 XHR 已完成,并且您可以运行您的断言。

这种方法的目的是避免修改您的代码,这会使您的测试无效。不幸的是,这也意味着您无法测试返回值本身,但我认为这将是任何不修改代码的策略的警告。

另一种方法是实际异步运行您的测试——即。使用 AOP 将您的断言附加到 onSuccess 回调。然而,许多测试套件不能很好地与异步测试配合使用,因为一个测试的设置可能在前一个测试的拆卸之前开始(即,因为前一个测试仍在等待异步调用返回)。

最后一种方法是模拟所有异步调用。IE。只需覆盖 XHR 并让您的测试断言它是使用正确的参数调用的。如果我有经过整个异步堆栈的集成测试,我可能会喜欢这种方法。

于 2011-03-11T21:46:00.453 回答