如何为CombineTest rxjs编写Jasmine单元测试用例
mycomponent.ts如何为CombineTest rxjs编写Jasmine单元测试用例,rxjs,angular2-services,angular2-observables,combinelatest,Rxjs,Angular2 Services,Angular2 Observables,Combinelatest,mycomponent.ts import { Component, OnInit } from '@angular/core'; import {FormGroup,FormControl} from '@angular/forms' import { DataServiceService } from './data-service.service'; import {combineLatest,Observable,pipe} from 'rxjs'; import {map,tap} f
import { Component, OnInit } from '@angular/core';
import {FormGroup,FormControl} from '@angular/forms'
import { DataServiceService } from './data-service.service';
import {combineLatest,Observable,pipe} from 'rxjs';
import {map,tap} from 'rxjs/operators';
import {Model} from './mode';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
constructor(private dataService: DataServiceService){}
name = 'Angular';
myForm: FormGroup;
observableResult$: Observable<any>;
ngOnInit(){
this.myForm = new FormGroup({
localId: new FormControl()
})
this.observableResult$ = combineLatest(
this.myForm.get('localId').valueChanges,
this.dataService.getDataFromURL(),
(localIdSelected, dataFromAPI) => ({localIdSelected,dataFromAPI})).
pipe(map(each => this.filterData(each.dataFromAPI,each.localIdSelected)));
this.observableResult$.subscribe(value => {
debugger
})
}
filterData(dataFromAPI,localIDSelected){
debugger
return dataFromAPI.filter(item => item.userId > Number(localIDSelected));
}
}
import { Injectable } from '@angular/core';
import {HttpClient} from '@angular/common/http'
import {Model} from './mode';
import {Observable} from 'rxjs';
@Injectable()
export class DataServiceService {
constructor(private http:HttpClient) { }
getDataFromURL():Observable<Model>{
return this.http.get<Model>('https://jsonplaceholder.typicode.com/todos');
}
}
const spyFilter = spyOn(component as any, filterData).and.callThrough();
const constAPIData$ = staticDataServiceMock.getAPIData();
spyOn(staticDataServiceMock, 'getAPIData').and.returnValue(
observableOf(countryStaticData$)
);
component.myForm.get('localId').setValue(1);
component.observableResult$.subscribe(value => {
expect(value[0].id==21).toBeTrue();
});
export class StaticDataMock{
static getAPIData(): Observable<StaticDataElements[]> {
return [
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
},
{
"userId": 1,
"id": 2,
"title": "quis ut nam facilis et officia qui",
"completed": false
},
{
"userId": 1,
"id": 3,
"title": "fugiat veniam minus",
"completed": false
},
{
"userId": 1,
"id": 4,
"title": "et porro tempora",
"completed": true
}];
}
}
staticDatamock.ts
import { Component, OnInit } from '@angular/core';
import {FormGroup,FormControl} from '@angular/forms'
import { DataServiceService } from './data-service.service';
import {combineLatest,Observable,pipe} from 'rxjs';
import {map,tap} from 'rxjs/operators';
import {Model} from './mode';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
constructor(private dataService: DataServiceService){}
name = 'Angular';
myForm: FormGroup;
observableResult$: Observable<any>;
ngOnInit(){
this.myForm = new FormGroup({
localId: new FormControl()
})
this.observableResult$ = combineLatest(
this.myForm.get('localId').valueChanges,
this.dataService.getDataFromURL(),
(localIdSelected, dataFromAPI) => ({localIdSelected,dataFromAPI})).
pipe(map(each => this.filterData(each.dataFromAPI,each.localIdSelected)));
this.observableResult$.subscribe(value => {
debugger
})
}
filterData(dataFromAPI,localIDSelected){
debugger
return dataFromAPI.filter(item => item.userId > Number(localIDSelected));
}
}
import { Injectable } from '@angular/core';
import {HttpClient} from '@angular/common/http'
import {Model} from './mode';
import {Observable} from 'rxjs';
@Injectable()
export class DataServiceService {
constructor(private http:HttpClient) { }
getDataFromURL():Observable<Model>{
return this.http.get<Model>('https://jsonplaceholder.typicode.com/todos');
}
}
const spyFilter = spyOn(component as any, filterData).and.callThrough();
const constAPIData$ = staticDataServiceMock.getAPIData();
spyOn(staticDataServiceMock, 'getAPIData').and.returnValue(
observableOf(countryStaticData$)
);
component.myForm.get('localId').setValue(1);
component.observableResult$.subscribe(value => {
expect(value[0].id==21).toBeTrue();
});
export class StaticDataMock{
static getAPIData(): Observable<StaticDataElements[]> {
return [
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
},
{
"userId": 1,
"id": 2,
"title": "quis ut nam facilis et officia qui",
"completed": false
},
{
"userId": 1,
"id": 3,
"title": "fugiat veniam minus",
"completed": false
},
{
"userId": 1,
"id": 4,
"title": "et porro tempora",
"completed": true
}];
}
}
导出类StaticDataMock{
静态getAPIData():可观察{
返回[
{
“用户ID”:1,
“id”:1,
“标题”:“授权或授权”,
“已完成”:false
},
{
“用户ID”:1,
“id”:2,
“标题”为“我的脸和办公室”,
“已完成”:false
},
{
“用户ID”:1,
“id”:3,
“标题”:“福吉亚威尼斯小号”,
“已完成”:false
},
{
“用户ID”:1,
“id”:4,
“标题”:“临时工”,
“已完成”:真
}];
}
}
我已经添加了我的测试用例来覆盖app.spec.ts中的CombineTest操作符和filterData,但是所需的代码失败了。我希望调用filterData失败了。CombineTest将触发valueChange事件并从API获取数据。我可以在spec文件中创建mock和setValue,但它仍然不起作用。好的,为了尝试帮助您进行这项工作,我使用您迄今为止提供的数据设置了一个Stackblitz。这是你的电话号码 我做了一些事情来让测试正常进行
- 我将
类中的StaticDataMock
方法类型更改为public,以便您可以从类外部调用它getAPIData()
- 我让方法返回()的
,将返回值转换为数据的可观察值,
- 我猜你实现了DataServiceService模拟,详情见Stackblitz
- 我创建了一个Jasmine spyObject来拦截服务中对
的调用,并返回您使用getDataFromURL()
创建的可观察对象StaticDataMock
- 我重新安排了规范中调用的顺序,并执行了
以显示console.log()
从不发出组件.observeResult$
更新 根据下面的评论,上面的Stackblitz链接已经更新,目前正在运行。Stackblitz的工作规范如下:
it('should change return of service.function1() only', () => {
fixture.detectChanges();
component.observableResult$.subscribe(value => {
console.log('observable Emitted, value is ', value);
expect(value[0].id==1).toBe(true);
});
component.myForm.get('localId').setValue(1);
});
关键是首先设置subscribe,然后在表单中发出一个新值,该值将更新combinelatetest()
并在subscribe()
中执行代码
我很高兴这能奏效 你的问题是什么?如果您希望有人帮助您编写测试用例,那么您需要非常清楚您到底要测试什么。您还需要显示更多的细节,例如,
mock.getIds()
是什么以及它返回什么,如果您已经设置了其他mock及其实现,测试床的细节(如果您正在使用),等等。@dmcgrandle:我已经更新了我的问题,请检查谢谢,我们正在接近。)我对各种文件的名称有点困惑。app.component.html
是mycomponent.ts
的模板吗?文件mycomponent.spec.ts
在哪里?另外,请展示整个设置和测试台实现-事实上,除了正在工作的规范之外,还有整个规范文件,您不需要帮助。您显示了StaticDataMock
类,但在您调用的规范中,staticDataServiceMock
——但没有显示这两个类之间的关系(甚至没有显示它们之间的关系)(我猜是您将其注入到TestBed[providers]数组中…),感谢您的努力!!!在调试过程中,我尝试了你的代码,但没想到我得到了未定义的订阅值。是的,这就是我在上面的讨论中所说的,在测试你的编码方式时,很难掌握可观测值。它可能需要重构,但只有你知道这段代码实际要实现什么-从你发布的内容到目前为止我还不清楚。我试图使用CombineTest()正确地链接观察值,我有两个控件,一个用于国家,另一个用于州,当国家更改第一个控件时(combineLatest的第一个参数),它应该触发combineLatest并从国家/地区服务获取相应的状态(combineLatest的第二个参数)。第二个参数的结果是conatins对象数组,然后我必须使用所选国家/地区(使用所选国家/地区-combineLatest的第一个参数)对其进行管道传输并过滤状态这与您提供的链接几乎相同,无法到达测试用例中的expect块。只需将component.myForm.get('localId').setValue(1);
移动到订阅之后,它就可以工作了。需要异步思考-一旦订阅被设置,我们就可以使用setValue(1)触发新的发射
,这将导致执行订阅。:)