gpt4 book ai didi

javascript - Jasmine/Karma 测试 Angular 5 HTTP 响应

转载 作者:行者123 更新时间:2023-12-01 01:45:44 24 4
gpt4 key购买 nike

我对 TDD 完全陌生,我正在尝试调试我们正在公司工作的一个大型 Angular 5 应用程序。

该应用程序运行良好,但现在我必须实现测试,并且我在创建最基本的入门测试的同时正在学习这些内容。我已经为主模块编写了这些内容,只是为了尝试这个工具:

describe('AppComponent', () => {
let httpClientSpy: { get: jasmine.Spy }
let dataReq: DataRequester;
let queryBuilder: PanelQueryBuilder;
let query: DataQuery;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
MainComponent,
Menu,
MessageViewer
],
imports: [
BrowserModule,
BrowserAnimationsModule,
routing,
AngularFontAwesomeModule,
FormsModule,
HttpModule,
ChartModule,
Ng4LoadingSpinnerModule.forRoot(),
NgbModule.forRoot()
],
providers: [
ReactiveService,
DataRequester,
{ provide: APP_BASE_HREF, useValue : '/' }
]
}).compileComponents();
}));
it('should create the app', async(() => {
const fixture = TestBed.createComponent(MainComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();

}));
it('userType should be defined', async(()=>{
expect(MainComponent.userType).toBeDefined();
}))

it('DataRequester exists and retrieves info', async(()=>{


beforeEach(() => {
// TODO: spy on other methods too
httpClientSpy = jasmine.createSpyObj('HttpClient', ['get']);
dataReq = new DataRequester(<any> httpClientSpy);
queryBuilder = new PanelQueryBuilder();
});



expect(MainComponent).toBeDefined();
}))
it('1. Build query and check integrity', async()=>{
query = queryBuilder.buildInitialQuery("panel", "conversions", 144);
expect(query).toBeDefined();
})

it('2. Send query and check result', async()=>{
dataReq.requestData(query, 'conversions').then( res => {
expect(res).toContain("panel");

})
})
});

我希望您专注于一个部分:DataRequester 服务。它是一个服务,有一个方法返回一个 promise ,并调用我们后端的特定部分,返回数据。我只是想在这里检查这个响应对象是否包含属性“panel”,以及测试...

...¡实际上说它存在!但是,如果我尝试将属性的名称更改为某些不存在的属性......它也验证为 true。所以也许,HTTP 请求在这里不能正常工作,在这里做错了什么。

我在这段代码中做了什么坏事吗?为什么 DataRequester“requestData”方法不能正确执行,Jasmine 无法在响应对象中正确测试我想要的条件?

最佳答案

是的,你在代码中做了一些不好的事情。但是别担心,我开始时也做了同样的事情。

首先,您必须了解单元测试的基础知识:进行单元测试是为了防止单元中的副作用

副作用是所需行为的变化:例如,您想将 div 着色为蓝色,经过一些代码编辑后,它变为红色:这是副作用。

单元是您正在测试的功能。在 Angular 中,您可以使用以下命令查看它是哪一个:

describe('AppComponent'

在这里,您正在测试 AppComponent

现在我们解决了这个问题,让我们看看您的测试中出了什么问题:您使用服务的真实实例。这意味着您不再使用单个单元:您正在测试多个单元。

更正该问题

你必须 mock 你的服务。您将检查您的组件是否实际上正在调用该服务,而不是该服务是否正在调用您的 API(这将通过服务本身的单元测试进行检查)。

在你的测试台上:

TestBed.configureTestingModule({
declarations: [
MainComponent,
Menu,
MessageViewer
],
imports: [
BrowserModule,
BrowserAnimationsModule,
routing,
AngularFontAwesomeModule,
FormsModule,
HttpModule,
ChartModule,
Ng4LoadingSpinnerModule.forRoot(),
NgbModule.forRoot()
],
providers: [
{
provide: ReactiveService,
useValue : {}
},
{
provide: DataRequester,
useValue: {}
},
{ provide: APP_BASE_HREF, useValue : '/' }
]

通常,组件仅处理 View :您不必真正模拟它们(尽管您应该)。

这允许您删除HttpModule在任何测试中都不需要它。

您还可以删除路由模块,因为 Angular 已经提供了它的模拟:RouterTestingModule

你的测试平台变成这样

TestBed.configureTestingModule({
declarations: [
MainComponent,
Menu,
MessageViewer
],
imports: [
BrowserModule,
BrowserAnimationsModule,
RouterTestingModule,
AngularFontAwesomeModule,
FormsModule,
ChartModule,
Ng4LoadingSpinnerModule.forRoot(),
NgbModule.forRoot()
],
providers: [
{
provide: ReactiveService,
useValue : {}
},
{
provide: DataRequester,
useValue: {}
},
{ provide: APP_BASE_HREF, useValue : '/' }
]

现在你有了一个合适的测试台。

剩下要做的就是在模拟的 useValue 中添加具有正确签名的组件使用的每个服务属性

例如,假设您的应用程序组件具有以下内容:

ngOnInit() {
this.dataRequester.requestWidth('URL').subscribe(res => this.reactiveService.width = res);
}

然后你的测试床就变成这样了:

TestBed.configureTestingModule({
declarations: [
MainComponent,
Menu,
MessageViewer
],
imports: [
BrowserModule,
BrowserAnimationsModule,
RouterTestingModule,
AngularFontAwesomeModule,
FormsModule,
ChartModule,
Ng4LoadingSpinnerModule.forRoot(),
NgbModule.forRoot()
],
providers: [
{
provide: ReactiveService,
useValue : {
width: 0
}
},
{
provide: DataRequester,
useValue: {
requestWidth: () => of(100)
}
},
{ provide: APP_BASE_HREF, useValue : '/' }
]

(模拟的值并不重要,您可以根据需要更改它们)

正如你所看到的,因为你的请求者服务返回一个 Observable,所以你也被迫返回一个。由于您的响应式(Reactive)服务存储宽度,因此您必须声明一个数字类型的变量。

现在,在您的测试中,使用前面的示例,您将执行以下操作:

it(`should get width from requester and store it in reactive service`, fakeAsync(() => {
spyOn(component['dataRequester'], 'requestWidth').and.callThrough();

component.ngOnInit();
tick();

expect(component['dataRequester'].requestWidth).toHaveBeenCalledWith('URL');
expect(component['reactiveService'].width).toEqual(100);
}));

你声明你要做什么(测试驱动),你监视你的服务(看看它是否被调用),然后你调用(因为我们的模拟已经是一个 Observable 并返回 100)。

然后,您调用该方法进行测试,并刷新异步调用(fakeAsynctick 是 Angular 的一部分,您可以在有关测试的文档中找到它们)。

最后,你提出你的期望。

至此,您成功测试了第一个方法!

关于javascript - Jasmine/Karma 测试 Angular 5 HTTP 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51984829/

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