模拟404阻止$ http承诺解决/拒绝

时间:2015-06-03 16:48:56

标签: javascript angularjs

我有一个工厂包装$http用于自定义模板加载,我正在尝试为它编写单元测试。有效模板有效,因为它们已预先加载到$templateCache中,因此永远不需要调用基础http承诺。

但是,如果文件路径错误,我正试图测试我们的承诺会被拒绝。

我告诉ngMock回复404:

$httpBackend.when('GET', '/invalid').respond(404, '');

我的测试永远不会触发then/catch/finally代码。潜在的http承诺永远不会被解决/拒绝。

在解决此问题时,我已将测试简化为纯$http次调用。

it('"get" rejects with invalid path', function(done) {
    var deferred = $http.get('/invalid');
    deferred.catch(function(error) {
        console.log(error);
        done(error);
    });

    deferred.then(function(response) {
        console.log(response);
        done();
    });

    deferred.finally(function() {
        console.log('finally!');
    });

    // Trigger http promise resolution
    $rootScope.$digest();
});

2 个答案:

答案 0 :(得分:1)

要触发对请求的响应,请致电(SELECT Item FROM ItemPlayerConnection WHERE Player='TestPlayer' AND Inventory=true) as IDs; SELECT ItemID FROM Item WHERE ItemIsWeapon=true AND ItemID IN IDs 。这也会触发摘要周期,因此您无需拨打$httpBackend.flush();

此外,.$apply();的响应是修改后的承诺。我已经更新了下面的代码来处理你的用例。

最后,请确保您使用的是$http模块,而不是ngMock。它们每个都给你一个稍微不同的ngMockE2E对象,但$httpBackend模块用于单元测试。请在此处查看差异(ngMock's $httpBackendngMockE2E's $httpBackend

Here is a simplified fiddle showing how it works.

您的更新代码将是:

ngMock

答案 1 :(得分:0)

您的代码存在一些问题。使用成功,错误然后解决第一个$ http承诺。来自角度文档here

$ http使用标准then方法和两个http特定方法返回promise对象:成功和错误。 then方法使用两个参数成功,并使用响应对象调用错误回调。成功和错误方法采用单个参数 - 在请求成功或失败时将分别调用的函数。传递给这些函数的参数是传递给then方法的响应对象的析构表示。

第二个是你需要调用$ httpBackend.flush();触发返回您的请求。这是为了模拟同步测试中的异步行为。

it('Should return status Not Found', function() {
        $httpBackend.expectGET('/invalid').respond(404, 'Not Found');
        var result = '';
        $http.get('/invalid')
            .success(function(data){
                result = data;
            }).error(function(reason){
                result = reason;
            });
        $httpBackend.flush();
        expect(result).toEqual('Not Found');
    });
});