Javascript 如何测试调用AJAX函数而不使用jasmine启动它的函数?

Javascript 如何测试调用AJAX函数而不使用jasmine启动它的函数?,javascript,jquery,angularjs,unit-testing,karma-jasmine-ajax,Javascript,Jquery,Angularjs,Unit Testing,Karma Jasmine Ajax,我已经登记了,但出于某种原因,他们不一定会拿出适合我的格式 我的问题是,我正在对一个函数进行单元测试,该函数调用发出AJAX请求的函数。我想在不触发AJAX请求(或停止该请求)的情况下测试外部功能,这样就不会将大量错误数据发送到数据服务器 下面是我的外部函数(它调用包含AJAX的函数): 以下是我的AJAX函数: vm.submit = function () { var d = $.ajax({ type: "POST" , data: angular.

我已经登记了,但出于某种原因,他们不一定会拿出适合我的格式

我的问题是,我正在对一个函数进行单元测试,该函数调用发出AJAX请求的函数。我想在不触发AJAX请求(或停止该请求)的情况下测试外部功能,这样就不会将大量错误数据发送到数据服务器

下面是我的外部函数(它调用包含AJAX的函数):

以下是我的AJAX函数:

vm.submit = function () {
    var d = $.ajax({
        type: "POST"
        , data: angular.toJson(vm.inputData)
        , url: "http://submit_the_data"
        , contentType: "application/json"
        , xhrFields: { withCredentials: true }
        , crossDomain: true
    })
    .success(function (resp) {
        DataService.ticketNumber = resp; // returns ticket# for the data model
    })
    .error(function (error) {
        DataService.ticketNumber = DataService.submitError;
    });
    d.then(function (d) {
        vm.loading = false; // stops the loading spinner
        DataService.tickets = []; // empty's the array to be filled anew
        $location.path('/submitted'); // success splash html
        $scope.$apply();
    });
};
spyOn(controller, 'submit').and.callFake(function() {
    DataService.ticketNumber = somevalue;
});
我已经编写了所有的测试来读取和验证
inputData
对象中的值,但是我不确定如何调用
clickSubmit()
,因此实际上没有向服务器提交任何内容。我在单元测试中已经达到了这一点:

'use strict';

describe('Controller: HomeController', function () {
    beforeEach(module('tickets'));
    var controller, scope, $location, DataService;
    var tests = 0;
    beforeEach(inject(function ($rootScope, $controller, _$location_, _DataService_) {
        $location = _$location_;
        DataService = _DataService_;
        scope = $rootScope.$new();
        controller = $controller('HomeController', {
            $scope: scope
        });
    }));
    afterEach(function () {
        tests += 1;
    });
    describe('clickSubmit should verify data and submit new ticket', function () {
        beforeEach(function () {
            jasmine.Ajax.install();
            controller.loading = false;
                ... // inputData fields filled in with test data
        });
        afterEach(function () {
            jasmine.Ajax.uninstall();
        });
        it('should start the spinner when called', function () {
            controller.clickSubmit();
            expect(controller.loading).toBeTruthy();
        });
        // other it('') tests
    });
    it('should have tests', function () {
        expect(tests).toBeGreaterThan(0);
    });
});
那么,在加载微调器上,在实际代码中取消对
vm.submit()
的调用之后应该做什么呢

谢谢


-C§

我建议模拟呼叫,而不是实际呼叫。粒度由您决定,您可以存根ajax调用,也可以存根整个提交函数

以下是如何存根submit函数:

vm.submit = function () {
    var d = $.ajax({
        type: "POST"
        , data: angular.toJson(vm.inputData)
        , url: "http://submit_the_data"
        , contentType: "application/json"
        , xhrFields: { withCredentials: true }
        , crossDomain: true
    })
    .success(function (resp) {
        DataService.ticketNumber = resp; // returns ticket# for the data model
    })
    .error(function (error) {
        DataService.ticketNumber = DataService.submitError;
    });
    d.then(function (d) {
        vm.loading = false; // stops the loading spinner
        DataService.tickets = []; // empty's the array to be filled anew
        $location.path('/submitted'); // success splash html
        $scope.$apply();
    });
};
spyOn(controller, 'submit').and.callFake(function() {
    DataService.ticketNumber = somevalue;
});
将该代码放在实际调用调用方的控制器之前。单击Submit()

然后,您可以跟进对间谍的期望,例如:

expect(controller.submit).toHaveBeenCalled()
或者任何其他与spyOn相关的期望

以下是茉莉花文档:
俯视“间谍”区域

如果要模拟ajax调用,必须模拟这样的承诺:

spyOn($, 'ajax').and.callFake(function() {
    var deferred = $q.defer();
    deferred.resolve(someResponse);
    return deferred.promise;
});

另外,为了让等待承诺解析的代码,在进行提交调用后,需要运行$scope.$digest(),以便angular能够处理承诺解析。然后,您可以检查您对依赖于承诺的解决方案或拒绝的代码的期望。

在my
updateData()
function“error:预期是间谍,但获得了函数”上出现错误。在加载inputData块之后,我将
spyOn
块放在每个
之前的
块中。这是这组测试中唯一失败的。
expect(controller.submit).tohavebeencall()已通过,因此我不明白为什么
updateData()
测试失败。没关系,使用
spyOn(控制器,'updateData')和.callThrough()使其工作。谢谢你的帮助。在模拟数据服务时,我可能会经常提到这一点(自从我把这个从控制器中移出后,它现在有3个AJAX调用)解决了我自己的问题。我得到了错误“$q未定义”,并意识到我只需要像这样注入它:
beforeach(inject(function($q){…}))