【问题标题】:Load local JSON into Jasmine/Karma Unit Test in AngularJS将本地 JSON 加载到 AngularJS 中的 Jasmine/Karma 单元测试中
【发布时间】:2017-03-18 15:50:47
【问题描述】:

我正在测试一个回调函数,它接受一个响应对象作为它的唯一参数。该对象是在其他地方发出的 HTTP 请求的响应,因此我不想在此测试中使用 $httpBackend,因为该请求与此函数无关。

它在 home.js 中,它是我的应用主页的控制器。

这是正在测试的函数:

 function submitLogin() {
      LoginService.login(loginPost, ctrl.username, ctrl.password, successCallback, errorCallback);
  }

// gets called in LoginService if login reponse is 201, otherwise errorCallback called
function successCallback(response) {
    // get details needed to determine correct forms for user
    var sessionData = {
      token: response.data.token,
      user_id: response.data.user_id,
      institution_name: response.data.institution_name,
      status: response.data.status,
      form_uri: getFormURI(response.data.forms) //extracts form URI for list of available forms for particular app
    };

    ctrl.formCheckInProgress = true;

    // update users forms from backend and cache them
    FormFetcherService.updateCachedForms(sessionData.user_id, sessionData.form_uri).then(function (response) {
      if (response == 'updated') {
        toastr.success('Your forms have been updated to the newest version', 'Forms Updated');
      }
      else {
        toastr.success('Your forms are already up-to-date', 'No Update     Required');
      }
    });

}

登录服务:

    angular.module('appName').service('LoginService', ['$http', function     ($http) {
    this.login = function (url, username, password, successCallback, errorCallback) {
        var data = {
            username: username,
            password: password
        };

        $http.post(url, $.param(data), {
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
                },
                timeout: 10000
            }
        ).then(successCallback, errorCallback);
    }
}]);

我想加载一个对象来代替传递给函数的“响应”对象。

有什么方法可以将 .json 文件放在我的 /tests 目录中,加载 JSON 并将其解析为 Javascript 对象,然后在我的单元测试中使用该对象?

我已经四处搜索,大多数解决方案都假设正在测试的功能中发出请求 - 这里不是这种情况。

干杯,

院长

【问题讨论】:

  • 显示你的控制器的代码,你可以模拟$http服务
  • 已编辑以显示正在测试的控制器的功能。
  • 显示该函数在代码中的引用位置
  • 现在显示LoginService.login :)
  • 完成 - 如果响应代码为 201,则从 LoginService 调用 successCallback。响应对象从 LoginService 内部传递给 successCallback。因此,要测试successCallback,只需传递从本地.json文件加载和解析的对象会更容易。

标签: javascript angularjs unit-testing jasmine karma-runner


【解决方案1】:

@dean-sherwin 虽然这实际上可能无法回答问题,但我想分享我一直用来从文件中加载 json 以进行 jasmine 测试的一段代码,因为:

  • 您并不总是希望将庞大的 json 数据保留在一个测试规范中
  • 如果需要,有助于跨多个规范共享该 json 数据

spyOn(SomeClass, 'someMethod').and.returnValue( $.ajax({ url: "somefolder/anotherfolder/theJSONFile.json", async: false, dataType: "json" }).then(function(data) { return data }) );

【讨论】:

    【解决方案2】:

    你可以这样做:

    var LoginService, $controller;
    
    var formFetcherService = {
        updateCachedForms: jasmine.createSpy('sessionData');
    }
    
    var response = {
        data: {
            user_id: 4,
            forms: 'some'
        }
    }
    
    beforeEach(module(function($provide) {
        $provide.value('LoginService', {
            login: function(url, username, password, successCallback, errorCallback) {
                successCallback(response);
            }
        });
    
        $provide.value('FormFetcherService', formFetcherService);
    }))
    
    beforeEach(inject(function(_$controller_) {
        $controller = _$controller_;
    });
    
    it('should create sessionData', function() {
        var controller = $controller('HomeController');
        controller.submitLogin();
        expect(formFetcherService.updateCachedForms).toHaveBeenCalledWith(response.user_id, response.form_uri);
    });
    

    【讨论】:

    • 感谢您迄今为止的帮助。对此,我真的非常感激。但这不仅仅是将 JSON 硬编码到单元测试文件中的一种更复杂的方法吗?巨大(数百个字段)的实际响应,这就是为什么我宁愿有类似的东西: var response = ;
    • @DeanSherwin,问题是你不能直接访问sessionData,所以你需要模拟formFetcherService服务。 JSON 在这里无关紧要,因为您正在测试 successCallback 函数,而您如何创建它并不重要。
    • 为什么不能直接访问sessiondata?测试是针对 HomeController 的,这是它声明的地方。因此,要单独测试该函数,我只需要“伪造”一个传递给它的响应对象并在最后检查输出,不是吗? (我是角度单元测试的新手)
    • 没有。不过稍后我会发布家庭控制器。谢谢你的帮助。我只是不认为从文件中加载 JSON 有什么大不了的。
    • 很抱歉让你挂在这上面。你的回答对我帮助很大。我刚刚开始对 Angular 进行单元测试,很多核心概念对我来说都是陌生的(尤其是使用 Jamsine 间谍)。我已将您的答案标记为正确,因为它的核心实现解决了我面临的问题,即使我没有完全使用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-27
    • 1970-01-01
    • 1970-01-01
    • 2018-07-07
    • 2016-03-25
    • 2014-05-04
    相关资源
    最近更新 更多