gpt4 book ai didi

Angular 单元测试 :WARN: 'Navigation triggered outside Angular zone, did you forget to call ' ngZone. 运行()'?'

转载 作者:行者123 更新时间:2023-12-03 15:56:00 55 4
gpt4 key购买 nike

我正在为从数据库中删除帐户的 Angular 应用程序编写单元测试。为此,我单击删除按钮。然后在 .ts 文件上调用函数。这将通过调用 API 删除帐户。

我想编写单元测试以查看是否使用 HttpTestingModule 调用此 API,它确实如此,但在帐户删除后的代码中,我使用 router.navigate 导航到不同的页面。当代码命中时,它会提示警告:“导航在 Angular 区域外触发,您是否忘记调用 'ngZone.run()'?”

ERROR: 'Unhandled Promise rejection:', 'Cannot match any routes. URL Segment: 'accountsList'', '; Zone:', 'ProxyZone', '; Task:', 'Promise.then', '; Value:', Error: Cannot match any routes. URL Segment: 'accountsList'
Error: Cannot match any routes. URL Segment: 'accountsList'
at ApplyRedirects.noMatchError (./node_modules/@angular/router/fesm5/router.js?:1455:16)
at CatchSubscriber.eval [as selector] (./node_modules/@angular/router/fesm5/router.js?:1436:29)
at CatchSubscriber.error (./node_modules/rxjs/_esm5/internal/operators/catchError.js?:40:31)
at MapSubscriber.Subscriber._error (./node_modules/rxjs/_esm5/internal/Subscriber.js?:89:26)
at MapSubscriber.Subscriber.error (./node_modules/rxjs/_esm5/internal/Subscriber.js?:69:18)
at MapSubscriber.Subscriber._error (./node_modules/rxjs/_esm5/internal/Subscriber.js?:89:26)
at MapSubscriber.Subscriber.error (./node_modules/rxjs/_esm5/internal/Subscriber.js?:69:18)
at MapSubscriber.Subscriber._error (./node_modules/rxjs/_esm5/internal/Subscriber.js?:89:26)
at MapSubscriber.Subscriber.error (./node_modules/rxjs/_esm5/internal/Subscriber.js?:69:18)
at ThrowIfEmptySubscriber.Subscriber._error (./node_modules/rxjs/_esm5/internal/Subscriber.js?:89:26), 'Error: Cannot match any routes. URL Segment: 'accountsList'
at ApplyRedirects.noMatchError (./node_modules/@angular/router/fesm5/router.js?:1455:16)
at CatchSubscriber.eval [as selector] (./node_modules/@angular/router/fesm5/router.js?:1436:29)
at CatchSubscriber.error (./node_modules/rxjs/_esm5/internal/operators/catchError.js?:40:31)
at MapSubscriber.Subscriber._error (./node_modules/rxjs/_esm5/internal/Subscriber.js?:89:26)
at MapSubscriber.Subscriber.error (./node_modules/rxjs/_esm5/internal/Subscriber.js?:69:18)
at MapSubscriber.Subscriber._error (./node_modules/rxjs/_esm5/internal/Subscriber.js?:89:26)
at MapSubscriber.Subscriber.error (./node_modules/rxjs/_esm5/internal/Subscriber.js?:69:18)
at MapSubscriber.Subscriber._error (./node_modules/rxjs/_esm5/internal/Subscriber.js?:89:26)
at MapSubscriber.Subscriber.error (./node_modules/rxjs/_esm5/internal/Subscriber.js?:69:18)
at ThrowIfEmptySubscriber.Subscriber._error (./node_modules/rxjs/_esm5/internal/Subscriber.js?:89:26)'

这是我尝试过的

test.spec.ts
 it ('should delete account, if account exist', ()=> {
let spyOnDelete = spyOn (component,'deleteRecord').and.callThrough();
fixture.detectChanges();
component.record.accountid = "Account1";
fixture.detectChanges();
let deleteButtonDOM = fixture.debugElement.query(By.css('#deletebtn'));
console.log(deleteButtonDOM.nativeElement);
deleteButtonDOM.triggerEventHandler('click',null);
fixture.detectChanges();
expect(spyOnDelete).toHaveBeenCalled(); //test passes

const req = _HttpTestingController.expectOne('/api/accounts/'+component.record.accountid);//test fails
expect(req.request.method).toBe("DELETE");
req.flush({status:"SUCCESS"});
expect(component.consoleMessages.includes("POST: SUCCESS in /api/accounts")).toBe(true);


..what must be written to
})


test.component.ts
  deleteRecord(id) {
this.spinner.show();
this.http.delete('/api/accounts/' + id)
.subscribe(res => {
this.spinner.hide();
if (res['status'] == "FAILURE") {
this.consoleMessages += "\nPOST: ERROR in /api/accounts\n" + JSON.stringify(res);
} else {
this.consoleMessages += "\nPOST: SUCCESS in /api/accounts\n" + JSON.stringify(res);
this.router.navigate(['/accountsList']);//this is creating the problem xxxxxxxxxxxxxxxx
}
}, (err) => {
this.consoleMessages += "\nPOST: ERROR in /api/accounts\n" + JSON.stringify(err);
this.spinner.hide();
console.log(err);
}
);
}

最佳答案

你应该模拟你的路由器。

我用 RouterTestingModule 做的方式.这是设置:

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule.withRoutes([
{ path: "", component: AccountComponent },
{ path: "**", redirectTo: "" }
])
],
declarations: [AccountComponent],
providers: []
}).compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(AccountComponent);
component = fixture.componentInstance;
router = TestBed.inject(Router);
fixture.detectChanges();
});

然后在你的测试中:

it('THEN: should navigate to /accounts', () => {
const ID_TO_DELETE = 1;
const routerNavigateSpy = jest
.spyOn(router, 'navigate')
.mockImplementation(() => of(true).toPromise());
component.deleteRecord(ID_TO_DELETE);
expect(routerNavigateSpy).toHaveBeenCalledWith(['/accounts']);
});

奖金

这篇文章解释了 Angular 区域的工作原理: ngZone

关于Angular 单元测试 :WARN: 'Navigation triggered outside Angular zone, did you forget to call ' ngZone. 运行()'?',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58220218/

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