【问题标题】:Testing an Angular Promise with Jasmine使用 Jasmine 测试 Angular Promise
【发布时间】:2013-11-12 03:40:46
【问题描述】:

以下测试一直失败,我不知道为什么?我正在尝试弄清楚如何使用 Jasmine 测试延迟/承诺。

错误

Expected undefined to be 'Resolved Data'.

测试

    describe('Queued Repository', function () {
    var ctrl,
        rootScope,
        scope,
        service;

    beforeEach(function () {
        module('testApp');

        inject(function ($rootScope, $controller, TestSrvc) {
            rootScope = $rootScope;
            scope = $rootScope.$new();
            service = TestSrvc;
        });
    });

    afterEach(inject(function ($rootScope) {
        $rootScope.$apply();
    }));

    it('test something', function () {
        expect(service.calculate(1, 5)).toBe(6);
    });

    it('resolves promises', function () {
        var result;

        service.getPromise().then(function (data) {
            result = data;
        });

        rootScope.$apply();
        expect(result).toBe('Resolved Data');
    });
});

服务

    var app = angular.module('testApp', []);

app.service('TestSrvc', ['$q', '$timeout', '$http', function ($q, $timeout, $http) {
    return {
        getPromise: function () {
            var d = $q.defer();

            $timeout(function () {
                d.resolve('Defered Result');
            }, 5000);

            return d.promise;
        },
        getSomething: function () {
            return "Test";
        },
        calculate: function (x, y) {
            return x + y;
        }
    }
}]);

【问题讨论】:

  • 不应该是expect(result).toEqual('Defered Result');吗?
  • @JonathanPalumbo - 是的,但它仍然不起作用。
  • 是的,我明白你的意思,结果是undefined。如果它是一个返回的承诺$http,我建议在做出断言之前致电$httpBackend.flush()。但是使用$q 服务是另一回事。

标签: javascript unit-testing angularjs jasmine


【解决方案1】:

尝试在expect(result).toBe('Resolved Data'); 之前调用$timeout.flush()

【讨论】:

  • 非常感谢!我还需要 $rootScope.$apply() 吗?
  • 我收到“意外请求”GET my.test.service/someObject/someId 没有预期的请求
  • 你没有显示你想要测试的文件的全部内容,这个 GET 调用来自哪里?为什么$http会被注入到服务中?
【解决方案2】:

在您的示例中,您需要同时调用 $timeout.flush()$rootScope.$apply()

解释:$timeout.flush() 将强制您在服务中的$timeout 立即运行。然后您的服务将调用'resolve' - 但promise.then() 直到下一个摘要周期才会被调用;因此,您需要调用 $rootScope.$apply() 来传播任何“解析”和“观察”——这将同步发生。

NOTE: 在 Jasmine 中,确保您的 promise.then() 函数出现在 BEFORE 您对 $rootScope.$apply 的调用中,否则它不会触发 promise.then() 函数。 (我还没弄清楚为什么 Jasmine 会出现这种情况。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-25
    • 2013-03-30
    • 1970-01-01
    • 1970-01-01
    • 2016-06-01
    • 1970-01-01
    相关资源
    最近更新 更多