久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

JasmineJS 測試中未觸發 AngularJS Promise 回調

AngularJS Promise Callback Not Trigged in JasmineJS Test(JasmineJS 測試中未觸發 AngularJS Promise 回調)
本文介紹了JasmineJS 測試中未觸發 AngularJS Promise 回調的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

限時送ChatGPT賬號..

我正在嘗試對包裝 Facebook 的 AngularJS 服務進行單元測試JavaScript SDK FB 對象;但是,測試不起作用,我一直無法弄清楚為什么.此外,服務代碼確實當我在瀏覽器中運行它而不是 JasmineJS 時工作單元測試,使用 Karma 測試運行器運行.

I'm trying to unit test an AngularJS service that wraps the Facebook JavaScript SDK FB object; however, the test isn't working, and I haven't been able to figure out why. Also, the service code does work when I run it in a browser instead of a JasmineJS unit test, run with Karma test runner.

我正在通過 $q<使用 Angular 承諾測試異步方法/代碼>目的.我將測試設置為使用 Jasmine 異步運行1.3.1 異步測試方法,但waitsFor()函數從不返回 true(見下面的測試代碼),它只是超時5 秒后.(Karma 尚未附帶 Jasmine 2.0 異步測試 API).

I'm testing an asynchronous method using Angular promises via the $q object. I have the tests set up to run asynchronously using the Jasmine 1.3.1 async testing methods, but the waitsFor() function never returns true (see test code below), it just times-out after 5 seconds. (Karma doesn't ship with the Jasmine 2.0 async testing API yet).

我想可能是因為 then() 方法承諾永遠不會被觸發(我有一個 console.log() 設置顯示那),即使我在異步調用 $scope.$apply()方法返回,讓 Angular 知道它應該運行一個摘要循環并觸發 then() 回調......但我可能是錯的.

I think it might be because the then() method of the promise is never triggered (I've got a console.log() set up to show that), even though I'm calling $scope.$apply() when the asynchronous method returns, to let Angular know that it should run a digest cycle and trigger the then() callback...but I could be wrong.

這是運行測試的錯誤輸出:

This is the error output that comes from running the test:

Chrome 32.0.1700 (Mac OS X 10.9.1) service Facebook should return false
  if user is not logged into Facebook FAILED
  timeout: timed out after 5000 msec waiting for something to happen
Chrome 32.0.1700 (Mac OS X 10.9.1):
  Executed 6 of 6 (1 FAILED) (5.722 secs / 5.574 secs)

代碼

這是我對服務的單元測試(查看解釋我目前發現的內容的內聯注釋):

'use strict';

describe('service', function () {
  beforeEach(module('app.services'));

  describe('Facebook', function () {
    it('should return false if user is not logged into Facebook', function () {
      // Provide a fake version of the Facebook JavaScript SDK `FB` object:
      module(function ($provide) {
        $provide.value('fbsdk', {
          getLoginStatus: function (callback) { return callback({}); },
          init: function () {}
        });
      });

      var done = false;
      var userLoggedIn = false;

      runs(function () {
        inject(function (Facebook, $rootScope) {
          Facebook.getUserLoginStatus($rootScope)
            // This `then()` callback never runs, even after I call
            // `$scope.$apply()` in the service :(
            .then(function (data) {
              console.log("Found data!");
              userLoggedIn = data;
            })
            .finally(function () {
              console.log("Setting `done`...");
              done = true;
            });
        });
      });

      // This just times-out after 5 seconds because `done` is never
      // updated to `true` in the `then()` method above :(
      waitsFor(function () {
        return done;
      });

      runs(function () {
        expect(userLoggedIn).toEqual(false);
      });

    }); // it()
  }); // Facebook spec
}); // Service module spec

這是我正在測試的 Angular 服務(查看解釋我目前發現的內容的內聯注釋):

And this is my Angular service that is being tested (see inline comments that explain what I've found so far):

'use strict';

angular.module('app.services', [])
  .value('fbsdk', window.FB)
  .factory('Facebook', ['fbsdk', '$q', function (FB, $q) {

    FB.init({
      appId: 'xxxxxxxxxxxxxxx',
      cookie: false,
      status: false,
      xfbml: false
    });

    function getUserLoginStatus ($scope) {
      var deferred = $q.defer();
      // This is where the deferred promise is resolved. Notice that I call
      // `$scope.$apply()` at the end to let Angular know to trigger the
      // `then()` callback in the caller of `getUserLoginStatus()`.
      FB.getLoginStatus(function (response) {
        if (response.authResponse) {
          deferred.resolve(true);
        } else {
          deferred.resolve(false)
        }
        $scope.$apply(); // <-- Tell Angular to trigger `then()`.
      });

      return deferred.promise;
    }

    return {
      getUserLoginStatus: getUserLoginStatus
    };
  }]);

資源

這是我已經查看過的其他資源的列表嘗試解決這個問題.

Resources

Here is a list of other resources that I've already taken a look at to try to solve this problem.

  • Angular API 參考:$q

這解釋了如何在 Angular 中使用 Promise,并給出了一個如何對使用 Promise 的代碼進行單元測試的示例(注意為什么 $scope.$apply() 需要被調用以觸發 then() 回調).

This explains how to use promises in Angular, as well as giving an example of how to unit-test code that uses promises (note the explanation of why $scope.$apply() needs to be called to trigger the then() callback).

Jasmine 異步測試示例

Jasmine Async Testing Examples

  • Jasmine.Async:使用 Jasmine 減少異步測試
  • 測試帶 Jasmine 2.0.0 的異步 Javascript

這些示例說明了如何使用 Jasmine 1.3.1 異步方法來測試實現 Promise 模式的對象.它們與我在自己的測試中使用的模式略有不同,該模式是根據直接來自 Jasmine 1.3.1 異步測試文檔.

These give examples of how to use the Jasmine 1.3.1 async methods to test objects implementing the Promise pattern. They're slightly different from the pattern I used in my own test, which is modeled after the example that comes directly from the Jasmine 1.3.1 async testing documentation.

StackOverflow 答案

StackOverflow Answers

  • 在 Angular JS 中未調用 Promise 回調
    • 答案1
    • 答案2

    請注意,我知道已經有其他適用于 Facebook JavaScript SDK 的 Angular 庫,例如:

    • angular-easyfb
    • angular-facebook

    我現在對使用它們不感興趣,因為我想學習如何自己編寫 Angular 服務.因此,請將答案限制在幫助我解決我的代碼中的問題,而不是建議我使用其他人的.

    I'm not interested in using them right now, because I wanted to learn how to write an Angular service myself. So please keep answers restricted to helping me fix the problems in my code, instead of suggesting that I use someone else's.

    那么,話雖如此,有人知道為什么我的測試不起作用嗎?

    推薦答案

    TL;DR

    從您的測試代碼中調用 $rootScope.$digest() ,它會通過:

    Call $rootScope.$digest() from your test code and it'll pass:

    it('should return false if user is not logged into Facebook', function () {
      ...
    
      var userLoggedIn;
    
      inject(function (Facebook, $rootScope) {
        Facebook.getUserLoginStatus($rootScope).then(function (data) {
          console.log("Found data!");
          userLoggedIn = data;
        });
    
        $rootScope.$digest(); // <-- This will resolve the promise created above
        expect(userLoggedIn).toEqual(false);
      });
    });
    

    Plunker這里.

    注意:我刪除了 run()wait() 調用,因為這里不需要它們(沒有執行實際的異步調用).

    Note: I removed run() and wait() calls because they're not needed here (no actual async calls being performed).

    詳細解釋

    這是發生了什么:當您調用 getUserLoginStatus() 時,它會在內部運行 FB.getLoginStatus(),而后者又會立即執行其回調,因為它應該這樣做,因為你已經嘲笑它來做到這一點.但是您的 $scope.$apply() 調用在該回調中,因此它在測試中的 .then() 語句之前執行.由于 then() 創建了一個新的 Promise,因此該 Promise 需要一個新的摘要才能得到解決.

    Here's what's happening: When you call getUserLoginStatus(), it internally runs FB.getLoginStatus() which in turn executes its callback immediately, as it should, since you've mocked it to do precisely that. But your $scope.$apply() call is within that callback, so it gets executed before the .then() statement in the test. And since then() creates a new promise, a new digest is required for that promise to get resolved.

    我相信這個問題不會發生在瀏覽器中,原因有二:

    I believe this problem doesn't happen in the browser because of one out of two reasons:

    1. FB.getLoginStatus() 不會立即調用其回調,因此任何 then() 調用都會首先運行;或
    2. 應用程序中的其他內容會觸發新的摘要循環.
    1. FB.getLoginStatus() doesn't invoke its callback immediately so any then() calls run first; or
    2. Something else in the application triggers a new digest cycle.

    因此,總結一下,如果您在測試中創建了一個承諾,無論是否明確,您都必須在某個時候觸發一個摘要循環才能解決該承諾.

    So, to wrap it up, if you create a promise within a test, explicitly or not, you'll have to trigger a digest cycle at some point in order for that promise to get resolved.

    這篇關于JasmineJS 測試中未觸發 AngularJS Promise 回調的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

    【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

How can I get my jasmine tests fixtures to load before the javascript considers the document to be quot;readyquot;?(在 javascript 認為文檔“準備好之前,如何讓我的 jasmine 測試裝置加載?) - IT屋-程序員軟件開發技術
What do jasmine runs and waitsFor actually do?(jasmine 運行和等待實際上是做什么的?)
How to provide mock files to change event of lt;input type=#39;file#39;gt; for unit testing(如何提供模擬文件來更改 lt;input type=filegt; 的事件用于單元測試)
How to unit test a chained method using Jasmine(如何使用 Jasmine 對鏈式方法進行單元測試)
How do I inject $rootScope into an AngularJS unit test?(如何將 $rootScope 注入 AngularJS 單元測試?)
Jasmine - How to spy on a function call within a function?(Jasmine - 如何監視函數中的函數調用?)
主站蜘蛛池模板: 欧美全黄| 国产一级视频在线观看 | 国产一区二区影院 | 天堂一区在线观看 | 欧美一区二区大片 | 韩日一区二区三区 | 91免费入口 | 野狼在线社区2017入口 | 国产一区二区三区 | 精品福利在线 | www.887色视频免费 | 99精品99| 91精品国产一区 | 欧美一级做性受免费大片免费 | av一二三区 | 国产高清视频 | 国产精品视频一区二区三区四区国 | 精品一区二区三区电影 | 久久精品综合网 | 日韩成人免费视频 | 1区2区3区视频 | 青青久久av北条麻妃海外网 | 色在线看 | 国产精品777一区二区 | 久久亚洲天堂 | 精品一区二区三区入口 | 久久精品色欧美aⅴ一区二区 | 精品综合久久 | 日韩精品极品视频在线观看免费 | 自拍视频在线观看 | 久久综合一区 | 日本精品视频在线观看 | 三级av网址 | 久久久久久国模大尺度人体 | 精品欧美乱码久久久久久 | 中文字幕国产一区 | 精品视频一区在线 | 欧美精品91| 欧美国产日韩在线观看 | 日韩欧美手机在线 | 性精品|