gpt4 book ai didi

angularjs - 测试使用数据表的 Angular Controller - 模拟 DTOptionsBuilder 和 DT ColumnBuilder

转载 作者:行者123 更新时间:2023-12-02 11:26:49 25 4
gpt4 key购买 nike

我正在尝试为主要从服务器创建值的数据表的 Angular Controller 编写测试。我试过 mock DTOptionsBuilder 和 DTColumnBuilder 但这似乎不起作用。我得到错误:

'undefined' 不是一个对象(评估 'DTOptionsBuilder.fromFnPromise(function(){
返回 MarketsFactory.getAll();
})
.withDataProp')

这是 Controller 代码:

.controller('MarketsCtrl', function($scope, $compile, $state, MarketsFactory, 

DTOptionsBuilder, DTColumnBuilder) {

$scope.edit = function(data){
$state.go('admin.market', {id:data});
};

//DATATABLES CONFIGURATIONS

$scope.dtInstance = {};

$scope.dtOptions = DTOptionsBuilder.fromFnPromise(function(){
return MarketsFactory.getAll();
})
.withDataProp('data.data')
.withOption('createdRow', function(row, data, dataIndex) {
$compile(angular.element(row).contents())($scope);
})
.withTableTools('http://cdn.datatables.net/tabletools/2.2.2/swf/copy_csv_xls_pdf.swf')
.withTableToolsButtons([
'copy',
'print', {
'sExtends': 'collection',
'sButtonText': 'Save',
'aButtons': ['csv', 'xls', 'pdf']
}
])
.withBootstrap()
.withBootstrapOptions({
TableTools: {
classes: {
container: 'btn-group right',
buttons: {
normal: 'btn btn-outline btn-default btn-sm'
}
}
}
});

$scope.dtColumns = [
DTColumnBuilder.newColumn('shortName').withTitle('Short Name').withClass('dt-left'),
DTColumnBuilder.newColumn('name').withTitle('Name').withClass('dt-left'),
DTColumnBuilder.newColumn('timezone').withTitle('Time Zone').withClass('dt-left'),
DTColumnBuilder.newColumn('id').renderWith(function(data, type, full) {
return '<a ng-click="edit(\'' + data + '\')">Edit</a>';
})];
})

和测试文件:
describe('Controller: MarketsCtrl', function () {
var scope, $state, DTOptionsBuilder, DTColumnBuilder;

beforeEach(function(){
var mockState = {};
var mockDTOptionsBuilder = {};
var mockDTColumnBuilder = {};

module('app', function($provide) {
$provide.value('$state', mockState);
$provide.value('DTOptionsBuilder', mockDTOptionsBuilder);
$provide.value('DTColumnBuilder', mockDTColumnBuilder);
});

inject(function() {

mockState.go = function(target) {
return target;
};

mockDTOptionsBuilder.fromFnPromise = jasmine.createSpy('DTOptionsBuilder.fromFnPromise');
mockDTOptionsBuilder.withDataProp = jasmine.createSpy('DTOptionsBuilder.withDataProp');

mockDTColumnBuilder.newColumn = jasmine.createSpy('DTColumnBuilder.newColumn');

});

});

beforeEach(inject(function ($controller, $rootScope, _$state_, _DTColumnBuilder_, _DTOptionsBuilder_) {
scope = $rootScope.$new();
$state = _$state_;
DTOptionsBuilder = _DTOptionsBuilder_;
DTColumnBuilder = _DTColumnBuilder_;

$controller('MarketsCtrl', {
$scope: scope,
$state: $state,
DTOptionsBuilder: DTOptionsBuilder,
DTColumnBuilder: DTColumnBuilder
});

scope.$digest();
}));


it('should provide an edit function', function () {
expect(typeof scope.edit).toBe('function');
});


});

我认为创建一个模拟并在其上放置一个 Spy 会阻止它调用链式函数,但我想不会。

我对测试很陌生,尤其是使用 Angular,所以任何一般的帮助都将不胜感激!

最佳答案

我从 sinonjs 接近这个/mocha背景

我在解密你的 beforeEach block 时遇到了一些麻烦 - 但它可以在某种程度上简化:

var $scope, $state, DTColumnBuilder, DTOptionsBuilder, createController;

beforeEach(function () {
DTColumnBuilder = {};
DTOptionsBuilder = {};
$state = {};

module('app', function ($provide) {
$provide.value('$state', $state);
$provide.value('DTColumnBuilder', DTColumnBuilder);
$provide.value('DTOptionsBuilder', DTOptionsBuilder);
});

inject(function ($controller, $injector) {
$scope = $injector.get('$rootScope').$new();
$state = $injector.get('$state');
DTColumnBuilder = $injector.get('DTColumnBuilder');
DTOptionsBuilder = $injector.get('DTOptionsBuilder');

createController = function () {
return $controller('MarketsCtrl', {
$scope: scope,
$state: $state,
DTOptionsBuilder: DTOptionsBuilder,
DTColumnBuilder: DTColumnBuilder
});
}
});

// Stub out the methods of interest.
DTOptionsBuilder.fromFnPromise = angular.noop;
$state.go = function () { console.log('I tried to go but.... I cant!!');
DTColumnBuilder.bar = function () { return 'bar'; };
});
spy 的性质是让原始实现做它的事情,但记录对所述函数的所有调用和各种相关数据。

一个 stub另一方面是 spy使用扩展的 API,您可以在其中完全修改所述功能的工作方式。返回值、预期参数等

假设我们使用了前面提到的 beforeEach block , DTOptionsBuilder.fromFnPromise将是 noop在此刻。因此, spy 是安全的并期望该方法已被调用。
it('should have been called', function () {
var spy = spyOn(DTOPtionsBuilder, 'fromFnPromise');
createController();
expect(spy).toHaveBeenCalled();
});

如果你想操纵所述函数的返回值,我会捕获 sinonjs并将其设为 stub .
it('became "foo"', function () {
DTOptionsBuilder.fromFnPromise = sinon.stub().returns('foo');
createController();
expect($scope.dtOptions).toEqual('foo');
});

现在,由于您正在使用 Promise,所以它有点复杂,但 stub 基于 Promise 的函数的基础是:
  • 注入(inject) $q进入你的规范文件。
  • 告诉 stub返回 $q.when(/** value **/) 的情况下已解决的 promise 。
  • 告诉 stub返回 $q.reject(/** err **/) 的情况下拒绝 promise 。
  • 运行$timeout.flush()刷新所有延迟任务。
  • 触发done回调以通知 Jasmine 您已完成等待异步任务(可能不需要)。这取决于测试框架/运行器。

  • 它可能看起来像这样:
    it('resolves with "foo"', function (done) {
    DTOptionsBuilder.fromFnPromise = sinon.stub().returns($q.when('foo'));
    expect($scope.options).to.eventually.become('foo').and.notify(done); // this is taken from the chai-as-promised library, I'm not sure what the Jasmine equivalent would be (if there is one).
    createController();
    $timeout.flush();
    });

    现在,很多这只是在这一点上的猜测。如果没有源代码在我旁边运行以供交叉引用,很难设置一个完整工作的测试套件,但我希望这至少会给你一些关于如何使用你的 spy 和 stub 的想法。

    关于angularjs - 测试使用数据表的 Angular Controller - 模拟 DTOptionsBuilder 和 DT ColumnBuilder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31328414/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com