Angularjs测试(Jasmine) - $ http返回'没有待处理的冲洗请求'

时间:2013-07-10 14:48:19

标签: unit-testing angularjs jasmine

我的UserManager服务每小时自动触发$ http POST以刷新用户访问令牌。

我正在尝试模拟该调用来验证令牌是否正在刷新,但是当我尝试刷新$ httpbackend时,我收到一条错误,说“没有待处理的请求刷新”,即使我知道刷新功能已经被调用(添加了一个console.log来验证)。

通过setTimeOut调用函数的事实是影响$ httpbackend还是我遗漏了其他东西。

下面的代码:

describe("UserManager Service Testing", function() {

    beforeEach(angular.mock.module('WebApp'));

    beforeEach(inject(function($httpBackend) {
        window.apiUrls = jQuery.parseJSON('{"cover_art": "http://myrockpack.com/ws/cover_art/?locale=en-us", "channel_search_terms": "http://myrockpack.com/ws/complete/channels/?locale=en-us", "register": "http://myrockpack.com/ws/register/", "categories": "http://myrockpack.com/ws/categories/?locale=en-us", "reset_password": "http://myrockpack.com/ws/reset-password/", "share_url": "http://myrockpack.com/ws/share/link/", "video_search": "http://myrockpack.com/ws/search/videos/?locale=en-us", "channel_search": "http://myrockpack.com/ws/search/channels/?locale=en-us", "video_search_terms": "http://myrockpack.com/ws/complete/videos/?locale=en-us", "popular_channels": "http://myrockpack.com/ws/channels/?locale=en-us", "popular_videos": "http://myrockpack.com/ws/videos/?locale=en-us", "login": "http://myrockpack.com/ws/login/", "login_register_external": "http://myrockpack.com/ws/login/external/", "refresh_token": "http://myrockpack.com/ws/token/"}');
        var mockLogin = {"token_type":"Bearer","user_id":"oCRwcy5MRIiWmsJjvbFbHA","access_token":"752a4f939662846a787a1474ad17ffddcd816dc7AAFB1G7HvgH-0qAkcHMuTESIlprCY72xWxyiuhySCpFJxKVYqOx9W7Gt","resource_url":"http://myrockpack.com/ws/oCRwcy5MRIiWmsJjvbFbHA/","expires_in":2,"refresh_token":"fa2f47f3590240e4bdfdbde03bf8042d"}
        var refreshToken = {"token_type":"Bearer","user_id":"CeGfSz6dQW2ga2P2tKb3Bg","access_token":"ef235de46dba53ba69ed049f57496ec902da5d28AAFB1HdeTE-2vwnhn0s-nUFtoGtj9rSm9waiuhySCpFJxKVYqOx9W7Gt","resource_url":"http://myrockpack.com/ws/CeGfSz6dQW2ga2P2tKb3Bg/","expires_in":3600,"refresh_token":"873e06747d964a0d80f79181c98aceac"};

        $httpBackend.when('POST', window.apiUrls.refresh_token).respond(refreshToken);
        $httpBackend.when('POST', window.apiUrls.login).respond(mockLogin);
    }));

    it('UserManager should refresh the token after 2 seconds', inject(function(UserManager, $httpBackend) {
        UserManager.oauth.Login('gtest','qweqwe');
        $httpBackend.flush();
        waits(4000);
        $httpBackend.flush();
        expect(UserManager.oauth.credentials.access_token).toEqual('ef235de46dba53ba69ed049f57496ec902da5d28AAFB1HdeTE-2vwnhn0s-nUFtoGtj9rSm9waiuhySCpFJxKVYqOx9W7Gt');
    }));
});

4 个答案:

答案 0 :(得分:3)

有关于此here的讨论。 “由于承诺是异步的,你需要在测试中使用$ rootScope。$ digest()来实现它们”

在$ httpBackend.flush()之前添加:

if(!$rootScope.$$phase) {
    $rootScope.$apply();
}

所以你的代码变成了:

it('UserManager should refresh the token after 2 seconds', inject(function(UserManager, $httpBackend) {
    UserManager.oauth.Login('gtest','qweqwe');

    if(!$rootScope.$$phase) {
        $rootScope.$apply();
    }

    $httpBackend.flush();
    expect(UserManager.oauth.credentials.access_token).toEqual('ef235de46dba53ba69ed049f57496ec902da5d28AAFB1HdeTE-2vwnhn0s-nUFtoGtj9rSm9waiuhySCpFJxKVYqOx9W7Gt');
}));

答案 1 :(得分:0)

我猜你必须将代码包装在run(...)块内的等待下面。否则,您的代码将在等待完成之前立即执行

    waits(4000);
    runs(function() {
        $httpBackend.flush();
        expect(UserManager.oauth.credentials.access_token).toEqual('ef235de46dba53ba69ed049f57496ec902        da5d28AAFB1HdeTE-2vwnhn0s-nUFtoGtj9rSm9waiuhySCpFJxKVYqOx9W7Gt');
    });

茉莉花文档中也有描述:https://github.com/pivotal/jasmine/wiki/Asynchronous-specs

答案 2 :(得分:0)

您的第一个$ httpBackend.flush()会刷新您在beforeEach()中定义的所有待处理请求。

当您第二次调用$ httpBackend.flush()时,没有待处理的请求,因此您会收到消息。

您需要在第一次刷新后添加另一个事件。

未经测试,但这是我的理论。

答案 3 :(得分:0)

所以我的茉莉花测试总是有时候我不得不使用正则表达式使网址变得不那么具体,大部分都是因为想要去除拖尾斜线或其他愚蠢的小东西。例如请求网址找不到期望请求,但下面的正则表达式会。

https://qa.com/sessions/5cdec5bde6a242dca2cf5dd0ff7be2c9

/(qa.com\/sessions\/5cdec5bde6a242dca2cf5dd0ff7be2c9)/g