【问题标题】:How to unit-test custom AJAX events如何对自定义 AJAX 事件进行单元测试
【发布时间】:2013-04-26 13:05:22
【问题描述】:

我有一个 javascript 应用程序,用户可以在其中搜索位置,然后显示在地图上。位置搜索是通过对服务器应用程序的 AJAX 调用完成的。有一个组件负责此服务器通信 (searchComponent),我想对通信是否正常进行单元测试。

自定义事件的描述

我的自定义事件是一个简单的发布/订阅实现,取自 http://api.jquery.com/jQuery.Callbacks/

var topics = {};
jQuery.Topic = function( id ) {
    var callbacks,
    method,
    topic = id && topics[ id ];
    if ( !topic ) {
        callbacks = jQuery.Callbacks();
        topic = {
            publish: callbacks.fire,
            subscribe: callbacks.add,
            unsubscribe: callbacks.remove
        };
        if ( id ) {
            topics[ id ] = topic;
        }
    }
    return topic;
};

最重要的方法是

  • EVENT.publish(data)
    触发事件并将数据传递给所有订阅者。

  • EVENT.subscribe(callback) 为事件订阅回调函数:只要事件被触发,回调函数就会被执行。

用例

基本的工作流程是这样的:

  • 用户点击搜索按钮
  • 应用程序调用searchComponent.doSearch()
  • searchComponent.doSearch() 向服务器发送请求
  • 服务器响应
  • searchComponent 为 either SEARCH_RESULTSEARCH_FAILED 触发 custom 事件
  • 应用程序监听这两个事件并从那里继续(在地图上显示内容或产生错误消息)

SEARCH_RESULTSEARCH_FAILED 是如上所述的自定义事件。

var SEARCH_RESULT = jQuery.Topic('SEARCH_RESULT');
var SEARCH_FAILED = jQuery.Topic('SEARCH_FAILED');

我想做什么?

我想测试一下 searchComponent 是否正常工作:

  • 对服务器的请求是否正确?
  • 是否正确处理了来自服务器的响应?
  • 当我拨打无效电话时搜索是否失败?
  • 服务器宕机时超时怎么办?

通常的东西。 ;)

问题终于 ;))

如何测试这个用例?
(最好使用 js-test-driver,尽管我愿意接受有关其他 javascript 测试框架的任何建议)

【问题讨论】:

    标签: javascript jquery ajax unit-testing publish-subscribe


    【解决方案1】:

    可以使用 js-test-driver 中的 [AsyncTestCase][1] 测试异步行为。

    这是 doSearch() 方法的示例测试用例。我添加了 cmets 来解释测试的每个部分都在做什么。

    MyTest = AsyncTestCase("MyTest", {
    
    testSearchGoodCase : function(queue) {
        // this flag will only be set to true when SEARCH_RESULT 
        // is triggered (see STEP 1)
        var resultReceived = false;
    
        // STEP 1
        queue.call('prepare callbacks', function(callbacks) {
    
            // add event handler for the desired behaviour
            var onExpectedBehaviour = callbacks.add(function() {
                // when this method is called the queue will enter STEP 2
                resultReceived = true;
            });
    
            SEARCH_RESULT.subscribe(onExpectedBehaviour);
    
            // What if our test-method is not working and an error occurs?
            // Then the SEARCH_FAILED event is triggered, but for this
            // test case that is an error. So we can add the onError method 
            // as an errback in js-test-driver.
    
            // errbacks cause the test to fail with a custom message.
            var onError = callbacks.addErrback('Received an error.');
    
            // When SEARCH_FAILED is triggered onError is called
            // -> that will cause the test to fail
            // with the error message "Received an error".
            SEARCH_FAILED.subscribe(onError);
    
            // Now everything is set up and we can execute the function
            // that we want to test.
            searchComponent.doSearch();
    
            // The test will then run until either SEARCH_RESULT
            // or SEARCH_FAILED is triggered. Or the test will
            // timeout (if none of the two events is triggered).
        });
    
        // STEP 2
        queue.call('check conditions after asynchronous method completed', function() {
    
            // when we get here the doSearch() method completed
            // its asynchronous task.
            assertTrue(resultReceived);
    
        });        
    }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-05-27
      • 2011-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多