【问题标题】:Angularjs testing (Jasmine) - $http returning 'No pending request to flush'Angularjs 测试 (Jasmine) - $http 返回“没有待处理的刷新请求”
【发布时间】:2013-07-10 14:48:18
【问题描述】:

我的 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');
    }));
});

【问题讨论】:

    标签: unit-testing angularjs jasmine


    【解决方案1】:

    有一个关于这个here的讨论。 “由于 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');
    }));
    

    【讨论】:

      【解决方案2】:

      我猜您必须将代码包装在运行(...)块内的等待下方。否则你的代码会在等待结束之前立即执行

          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

      【讨论】:

        【解决方案3】:

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

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

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

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

        【讨论】:

          【解决方案4】:

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-09-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-10-31
            • 1970-01-01
            相关资源
            最近更新 更多