2

私はrubyのハーモニーを使用して構築したいくつかのjavascriptライブラリをテストしています。AJAX呼び出しを除いて、すべてが完全に機能しています—これを達成する方法について誰かが何かアイデアを持っていますか?

私のコードは次のようになります(私は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非同期コールバックの結果を取得できるように、上記をどのように割り当てる必要があるかということです。

4

1 に答える 1

0

非同期呼び出しは、一般的に JS 単体テストで問題になります。XHR呼び出しが成功するまでメインスレッドをブロックすることにより、XHR呼び出しを効果的に同期させることで、過去に解決しました。これを行う方法はフレームワークによって異なります。私は Harmony と RightJS に慣れていません。ただし、ロジックは次のようになります。

  1. XHR メソッドをオーバーライドして、ロック/ミューテックスを維持します。ロックは単純なブール値にすることができます。XHR が処理中の場合、ロックは になりtrue、処理中の XHR がない場合、ロックは になりますfalse
  2. テストでは、アサーションを実行する前に、XHR を実行し、ロックがクリアされるまで待機するループを追加します。
  3. ループが終了すると、XHR が完了したことを確認し、アサーションを実行できます。

このアプローチの目的は、テストを無効にするコードの変更を避けることです。残念ながら、これは戻り値自体をテストできないことも意味しますが、これはコードを変更しない戦略の警告になると思います。

別のアプローチは、実際にテストを非同期で実行することです。AOP を使用して onSuccess コールバックにアサーションをアタッチします。ただし、多くのテスト スイートは、非同期テストではうまく動作しません。これは、1 つのテストのセットアップが前のテストのティアダウンの前に開始される可能性があるためです (つまり、前のテストがまだ非同期呼び出しの戻りを待っているため)。

最後のアプローチは、すべての非同期呼び出しをモックすることです。すなわち。XHR をオーバーライドして、正しい引数で呼び出されたことをテストでアサートします。非同期スタック全体を通過する統合テストがある場合は、このアプローチを好むかもしれません。

于 2011-03-11T21:46:00.453 に答える