如何对自定义 AJAX 事件进行单元测试

Posted

技术标签:

【中文标题】如何对自定义 AJAX 事件进行单元测试【英文标题】:How to unit-test custom AJAX events 【发布时间】: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 测试框架的任何建议)

【问题讨论】:

【参考方案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);

    );        


【讨论】:

以上是关于如何对自定义 AJAX 事件进行单元测试的主要内容,如果未能解决你的问题,请参考以下文章

WPF - 对自定义标记扩展进行单元测试

如何对自定义 Jackson JsonSerializer 进行单元测试?

Angular2如何对自定义验证器指令进行单元测试?

对自定义 symfony 约束进行单元测试

如何测试自定义单元格是不是已向 tableView 注册?

MVC 自定义过滤器,手动调用 ASP.NET 管道事件进行单元测试