gpt4 book ai didi

javascript - 测试 Angularjs 1.6 中 $q.all() 的 then 中设置的公共(public)值

转载 作者:行者123 更新时间:2023-11-28 04:52:28 24 4
gpt4 key购买 nike

我正在尝试使用 $componentController 测试 Angular 分量我只是想测试公共(public)代码的输入和输出,因此在我的 Controller 中,“this.data”属性具有最高优先级。从输入 this.data 开始很简单,因为它只是测试类构造函数 prop,默认设​​置为 undefined

输出是问题所在,在获得预期值之前需要调用很多代码。

问题:

如何附加到 $q.all.resolve() 并测试 this.data 的映射输出?期望是 expect(ctrl.data).toEqual(expectedData).

Controller.js:

class Controller {
/**
* @ngInject
*/
constructor(
someService, $q, $scope) {
this.ngScope_ = $scope;
this.someService_ = someService;
this.ngQ_ = $q;
this.data = undefined;
}

$onInit() {
this.getData_();
}

getData_() {

let requests = [1,2];
const REQUEST_TYPE = 'SOME_REQUEST';
const outEachApproval = (d) => d[0].approvals;
const requestsAsArr = requests.split(',');
const promiseArr = requestsAsArr.map(
(i) => this.someService.getAllDataByType(
REQUEST_TYPE, i));

this.ngQ_.all(promiseArr).then((data) => {
this.data = data.map(outEachApproval); // How the hell do I test this.data at this point in time in the unit test?
});
}

Controller_test.js

describe('someModule', ()=> {


let $componentController,
ctrl,
$rootScope,
$q;

const mockData = [[{approvals: [{name: 'hey'}]},{approvals: [{name: 'hey'}]}]];
const expectedData = [[{name:'hey'}],[{name:'hey'}]];
beforeEach(() => {
module(someModule.name);

inject((_$componentController_, _$rootScope_, _$q_) => {

$componentController = _$componentController_;
$q = _$q_;
$rootScope = _$rootScope_;
});


ctrl = $componentController(COMPONENT_NAME,
{
$scope: $rootScope.$new(),
someService: {
getAllDataByType: () => {
return Promise.resolve(mockData);
}
}
}, {});
});

describe('this.data input', ()=> {
it('should be undefined', () => {
expect(ctrl.data).toBeUndefined();
});
});

describe('this.data output', ()=> {
it('should be equal to expectedData after init', (done) => {
ctrl.$onInit();
expect(ctrl.data).toEqual(expectedData);
ctrl.ngScope_.$apply();
done();
});
});
});

最佳答案

我看到了几种处理它的方法:

第一

首先让您的 someService 模拟在您的测试中可用:

let someServiceMock = {
getAllDataByType: () => {
//we can leave this empty
}
};

...

beforeEach(() => {

...

ctrl = $componentController(COMPONENT_NAME,
{
$scope: $rootScope.$new(),
someService: someServiceMock
}, {});

});

然后在你的测试中简单地监视它:

describe('this.data output', ()=> {
it('should be equal to expectedData after init', (done) => {
//as we use $q.all(), we need to create array of promises
let deferred1 = $q.defer();
...
let deferredN = $q.defer();
let arrayOfPromises = [deferred1.promise, ... ,deferredN.promise];
//then we spy on needed method and mock its return value
spyOn(someServiceMock, 'getAllDataByType').and.returnValue(arrayOfPromises);
ctrl.$onInit();
expect(someServiceMock.getAllDataByType).toHaveBeenCalled();
//now we resolve our promises with any data we want
let resolveData1 = /*Promise#1 mocked data*/;
deferred1.resolve(resolveData1)
let resolveData2 = /*Promise#2 mocked data*/;
deferred2.resolve(resolveData2)
...
let resolveDataN = /*Promise#N mocked data*/;
deferredN.resolve(resolveDataN)
//$q.all() returns array, so expectedData would be array
let expectedData = [
resolveData1,
resolveData2,
...
resolveDataN
];
//then we need to apply changes
$rootScope.$apply();
expect(ctrl.data).toEqual(expectedData);
ctrl.ngScope_.$apply();
done();
});
});

Here是一个简单的插件,可以使用多个 $q.defer() 实例。

顺便说一句,如果 someServiceMock.getAllDataByType() 中的请求是通过 Angular 实现的 $http ,然后你可以用 $httpBackend 来模拟它们服务。

<小时/>

第二个

在组件 Controller 中为 $q 服务创建模拟:

let $qMock = {
all: () => {
//we can leave this empty
}
}

...

beforeEach(() => {

...

ctrl = $componentController(COMPONENT_NAME,
{
$scope: $rootScope.$new(),
someService: {
getAllDataByType: () => {
return Promise.resolve(mockData);
}
},
$q: $qMock
}, {});

});

然后在你的测试中简单地监视它:

describe('this.data output', ()=> {
it('should be equal to expectedData after init', (done) => {
let deferred = $q.defer();
spyOn($qMock, 'all').and.returnValue(deferred.promise);
ctrl.$onInit();
expect($qMock.all).toHaveBeenCalled();
deferred.resolve(expectedData);
//now we need to apply changes
$rootScope.$apply();
expect(ctrl.data).toEqual(expectedData);
ctrl.ngScope_.$apply();
done();
});
});

此测试更简单,但请注意,它不依赖于 someService.getAllDataByType() 将返回的内容。

<小时/>

有关该主题的一些有用文章:

关于javascript - 测试 Angularjs 1.6 中 $q.all() 的 then 中设置的公共(public)值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42796656/

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