我正在嘗試在我的一個組件中執行一些測驗。我正在使用通過管道傳輸到 ActivatedRoute 的 paramMap 的 observable,以便從 URL 獲取 guid,并使用 switchMap 將回應中的值分配給組件變數。我的觀點是使用 observable 在螢屏上顯示資料,當我通過 cli 為應用程式提供服務時,一切似乎都運行良好。
一旦我嘗試為我的組件執行測驗,ExpressionChangedAfterItHasBeenCheckedError就會顯示在 Karma 的瀏覽器選項卡中。
我相信錯誤是由于我正在更改 isBranded 變數的值而引起的,但我需要它在視圖中顯示正確的徽標。

我的組件代碼:
@Component({
selector: 'app-digital-payment',
templateUrl: './digital-payment.component.html',
styleUrls: ['./digital-payment.component.scss']
})
export class DigitalPaymentComponent implements OnInit {
cdnUrl = environment.cdnUrl;
isBranded = false;
payment$: any;
constructor(private service: DigitalPaymentService, private activeRoute: ActivatedRoute) {
}
ngOnInit() {
this.payment$ = this.activeRoute.paramMap.pipe(switchMap((params: any) => {
let guid = params.get('guid');
return this.service.checkPaymentStatus(guid).pipe(map((data: any) => {
this.isBranded = data.isBranded;
return data;
}));
}));
}
}
我的觀點:
<header>
<a class="logo">
<img src="{{ cdnUrl }}/Image/not-branded-logo.svg" alt="Not Branded Logo" />
</a>
<a class="logo pull-right text-right" *ngIf="isBranded">
<img src="{{ cdnUrl }}/Image/branded-logo.svg" alt="Branded Logo" />
</a>
</header>
<section>
<div class="payment-status {{ payment.class }}" *ngIf="payment$ | async as payment; else loading">
<mat-icon *ngIf="payment.icon">{{ payment.icon }}</mat-icon>
<h1>{{ payment.heading }}</h1>
<p>{{ payment.text }}</p>
</div>
<ng-template #loading>
<h1 class="loading-heading">Loading</h1>
<p>Please wait until your request has been executed.</p>
</ng-template>
</section>
我的服務:
@Injectable({
providedIn: 'root'
})
export class DigitalPaymentService {
private apiUrl: string = 'digitalpaymentexternal/';
private statusBinding = {
Success: {
class: 'success',
icon: 'check_circle_outline',
heading: 'Successful',
text: 'Your payment plan has been confirmed.'
},
Failed: {
class: 'fail',
icon: 'highlight_off',
heading: 'Transaction failed',
text: 'Please try a different payment method.'
},
Invalid: {
class: 'fail',
icon: 'error_outline',
heading: 'Incorrect link',
text: 'This link is invalid or it has been expired.'
}
};
constructor(private requester: RequesterService) { }
checkPaymentStatus(guid): Observable<any> {
return this.requester.post<void>(this.apiUrl 'CheckPaymentStatus', guid).pipe(map((data: any) => {
return { ...this.statusBinding[data.status], isBranded: data.isBranded };
}));
}
}
還有我的組件測驗代碼:
describe('DigitalPaymentComponent', () => {
let component: DigitalPaymentComponent;
let fixture: ComponentFixture<DigitalPaymentComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [DigitalPaymentComponent],
providers: [
{
provide: DigitalPaymentService,
useValue: {
checkPaymentStatus: guid => of({ isBranded: true })
}
},
{
provide: ActivatedRoute,
useValue: {
paramMap: of(convertToParamMap({ guid: '00000000-0000-0000-0000-000000000000' }))
},
},
]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DigitalPaymentComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
uj5u.com熱心網友回復:
可能的解決方案是在this.cdr.detectChagnes();內部添加ngOnInit()or ngAfterViewInit()。cdr指ChangeDetectionRef.
constructor(..., private cdr: ChangeDetectionRef) {}
ngOnInit() {
...
// for karma test to avoid ExpressionChangedAfterItHasBeenCheckedError error issue
this.cdr.detectChagnes();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/491199.html
下一篇:方法單元測驗在nestjs中失敗
