2

我的 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

4 回答 4

3

这里有一个关于这个的讨论。“由于 Promise 是异步的,您需要在测试中执行 $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');
}));
于 2013-10-25T10:07:45.940 回答
0

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

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

它也在 jasmine 文档中进行了描述:https ://github.com/pivotal/jasmine/wiki/Asynchronous-specs

于 2013-07-15T13:13:45.527 回答
0

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

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

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

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

于 2013-10-07T18:56:32.130 回答
0

因此,在我的茉莉花测试中,有时我不得不使用正则表达式来使 url 不那么具体,其中大部分都是有角度的,想要去除斜杠或其他愚蠢的小东西。例如请求 url 不会找到期望的请求,但下面的正则表达式会。

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

/(qa.com\/sessions\/5cdec5bde6a242dca2cf5dd0ff7be2c9)/g
于 2017-04-26T20:20:15.960 回答