读取 json 文件的 Karma+Jasmine 函数总是失败

Karma+Jasmine function that reads a json file always fails

我很难理解 Karma+Jasmine 的单元测试是如何工作的

我正在尝试为我的 AngularJS 应用程序设置一些单元测试,但我 运行 遇到了一个问题,测试似乎没有 运行 一个功能正确。

我有一个函数可以通过 $http.get 请求读取 json 文件并填充数组,但是当我在单元测试中设置期望数组的长度时 expect(array.length).toBe(10),总是失败,但那是我正常运行 App时数组的长度。实际上,如果我在单元测试中打印 console.log 中的长度,它似乎总是停留在 1.

但是例如,如果我检查我手动声明的一些变量,那么 expect 函数就可以正常工作。

谁能告诉我我到底错过了什么?看来我缺少一些关于如何使用 Karma/Jasmine 进行单元测试的基础知识。

如有任何帮助,我们将不胜感激。谢谢!

你的问题是 $http.get 是一个异步方法。除非您特别告诉 angularjs 它需要刷新该响应,否则它不会。该方法将退出并且 $http.get 的回调不会及时发生,您的 it 方法无法利用其 $scope 转换。

您可以通过期望使用 $httpBackend API https://docs.angularjs.org/api/ngMockE2E/service/$httpBackend

进行调用来实现此目的

然后你可以

$httpBackend.expectGET('../json/apps.json').respond(200, {mock: 'api response');
$scope.getAllApps();
$httpBackend.flush();
expect(scope.allApps.length).toBe(10);

在您的单元测试中,您永远不应依赖 http 调用的实际响应。为确保您只测试方法,您应该始终模拟 API 应该 return.

的响应

ERRONEOUS

$scope.getAllApps = function(){
    $scope.isLoading = true;
    $http.get('../json/apps.json').then(function (data){
        // ...
    });
    $scope.isLoading = false;
};

更好

$scope.getAllApps = function(){
    $scope.isLoading = true;
    $http.get('../json/apps.json').then(function (data){
        // ...
    }).finally(function() {
        $scope.isLoading = false;
    });
};

因为 $http 服务是非阻塞和异步的,它立即 return 是一个承诺。它不会等待来自服务器的数据 return。 isLoading 标志需要等待 promise 解析后才能设置标志 false.