【问题标题】:Async callback was not invoked within timeout - Unit testing a Typescript & Angular $http service超时内未调用异步回调 - 单元测试 Typescript 和 Angular $http 服务
【发布时间】:2015-07-06 14:39:07
【问题描述】:

我正在尝试在 Angular 中测试使用 $http 的服务,但大约 5 秒后(茉莉花超时)我得到:

错误:超时 - 在 jasmine.DEFAULT_TIMEOUT_INTERVAL 指定的超时内未调用异步回调。

错误:超时 - 在 jasmine.DEFAULT_TIMEOUT_INTERVAL 指定的超时内未调用异步回调。

我尝试过使用 $rootScope.$digest(),但这似乎没有任何区别。测试(和应用程序代码)是用 Typescript 编写的,代码在实际应用程序中运行良好。

我没有看到提示 then() 已运行的警报/日志,但我确实设法在测试中使用 setTimeout() 发出警报(没有应用程序更改),但我仍然遇到错误。

测试代码

  var $httpBackend, orderSearchService;
        beforeEach(inject((_$httpBackend_, _orderSearchService_) => {
            $httpBackend = _$httpBackend_;
            orderSearchService = _orderSearchService_;
            $httpBackend.expectGET("http://testUrl/api/search/testquery");
            $httpBackend.whenGET("http://testUrl/api/search/testquery").respond(200, "testData");
        }));

        it("can call $http and retrieve results",(done) => {
            orderSearchService.search("testquery").then(promise => {
                var results = promise.data;
                alert(results);
                expect(results).toBe("testData");
                $httpBackend.flush();
                done();
            });
        });

服务摘录:

public search(term: string): angular.IPromise<any> {
        var result: angular.IPromise<any> = this.httpService.get("http://testUrl" + "/api/search/" + term)
            .success((data: any) => { return data });
        return result;
    }

我的理解是测试应该调用search(),Jasmine应该等待done()被调用。

【问题讨论】:

  • 您已跳过在单元测试中调用 $digest() 方法。 Angular 不知道何时执行.then() 方法

标签: angularjs unit-testing asynchronous jasmine


【解决方案1】:

翻译成 JavaScript 后会变成这样($httpBackend.flush() 在内部运行摘要循环) 我还提取了查询参数以阻止 DRY 违规

angular
  .module('app', [])
  .service('orderSearchService', function($http) {
    this.search = function(term) {
      return $http.get("http://testUrl" + "/api/search/" + term).success(function(data) {
        return data;
      })
    }
  });



describe('orderSearchService', function() {
  var $httpBackend, orderSearchService;

  beforeEach(module('app'));

  beforeEach(inject(function(_$httpBackend_, _orderSearchService_) {
    $httpBackend = _$httpBackend_;
    orderSearchService = _orderSearchService_;
  }));

  it("can call $http and retrieve results", function() {
    var query = {
      q: 'testquery',
      response: 'testData'
    };


    $httpBackend.expectGET(/http:\/\/testUrl\/api\/search/);
    $httpBackend.whenGET(new RegExp('http://testUrl/api/search/' + query.q)).respond(200, query.response);

    orderSearchService.search(query.q).then(function(promise) {
      var results = promise.data;
      expect(results).toBe(query.response);
    });
    $httpBackend.flush();
  });
});
<link href="//safjanowski.github.io/jasmine-jsfiddle-pack/pack/jasmine.css" rel="stylesheet" />
<script src="//safjanowski.github.io/jasmine-jsfiddle-pack/pack/jasmine-2.0.3-concated.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular-mocks.js"></script>

【讨论】:

  • 谢谢,我在 Typescript 中进行了更改,还必须在之前的 beforeEach() 中删除未使用的 $provide。我不知道为什么它仍然被 $provide 破坏。
  • 您在 Angular 无法访问的方法内部调用了 $httpBackend.flush(),因为 thenflush() 之后执行
猜你喜欢
  • 1970-01-01
  • 2017-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-05
  • 1970-01-01
  • 2012-04-28
  • 1970-01-01
相关资源
最近更新 更多