我正在将Angular 8与Karma一起使用。 Karma的新手,所以我希望这很简单。
运行单元测试时,我收到“失败:无法读取未定义的属性'subscribe'”。调用堆栈指示我正在使用订阅的TimesheetComponent.getUserRole方法。因此,错误是该组件方法中的datasvc在Karma中未定义。不确定如何定义。
我在组件使用的服务上创建了createSpyObj,但我收到错误消息。这是代码-
tk-timesheet.component.ts-
import { Component, OnInit } from '@angular/core';
import 'ag-grid-community';
import { throwError, Subscription, forkJoin } from 'rxjs';
import {GridOptions} from 'ag-grid-community';
import { TkDataService } from '../tk-services/tk-data/tk-data.service';
interface DayAssignments {
dayOfWeek: string;
date: string;
}
@Component({
selector: 'app-timesheet',
templateUrl: './tk-timesheet.component.html',
styleUrls: ['./tk-timesheet.styles.scss']
})
export class TimesheetComponent implements OnInit {
public gridOptions: GridOptions;
public columnDefs: any;
public defaultColDef: any;
public rowData: any;
public chargeCodes: any;
public weekOfOptions: any;
public weekDates: object[] = [];
public userRoles: {};
public shifts: []
public thisUser: {User}
public thesePayPeriods: any
public thisPayPeriod: any
public commentCode: any
public commentCodes: any
subscription: Subscription;
weekOf: any = 'current';
comment = '';
constructor(
private dataSvc: TkDataService
) {
this.gridOptions = {
enableSorting: true,
enableFilter: false,
rowStyle: {color: '#84613D'},
headerStyle: {color: '#84613D'}
} as GridOptions;
this.defaultColDef = [
{
resizable: true,
}
];
this.weekOfOptions = [
'current',
'previous'
];
this.commentCodes = [
'CH', 'PTO', 'HOL'
]
}
private canWrite: boolean;
getUserRole(): any {
return this.dataSvc.post('getuserdata', {})
.subscribe(res => {
this.userRoles = res;
console.log('this.userRoles inside tk-timesheet component::: ', this.userRoles);
});
}
forkJoin([
this.dataSvc.getUserId('userid', ''),
this.dataSvc.getOpenPayPeriods("payperiods/open", {status: "open"}),
this.dataSvc.getChargeCodes('chargeCodes', '')
])
.subscribe((data) => {
let userData = data[0]
let payPeriods = data[1]
this.thesePayPeriods = payPeriods
this.weekOfOptions = this.thesePayPeriods.map(period => {
let dateString = period.startdate //use thesePayPeriods to set weekOfOptions options.
let newDate = new Date(dateString.replace('T', ' '))
let shortNewDate = newDate.toString().split(' ')
console.log('shortNewDate', shortNewDate)
let result = `${shortNewDate[0]} ${shortNewDate[1]} ${shortNewDate[2]} ${shortNewDate[3]}`
return result
})
this.thisPayPeriod = payPeriods[0] //use weekOfOptions selection to set this.thisPayPeriod dynamically.
let chargeCodes = data[2]
this.chargeCodes = chargeCodes
console.log('data from forkJoin:: ', data, 'userData::: ', userData[0].userid, 'payPeriods:: ', payPeriods, 'chargeCodes:: ', chargeCodes)
this.dataSvc.getShifts(`shifts/${userData[0].userid}/${payPeriods[0].payperiodid}`, data).subscribe((shifts: any) => {
this.shifts = shifts
this.rowData = this.buildRowData(shifts, chargeCodes)
})
}, (err) => { /* do error stuff*/})
//this.getUserRole();
this.getUserRole();
this.getMonday();
}
tk-timesheet.spec.ts-
import { TestBed, async, ComponentFixture, inject, tick, fakeAsync} from '@angular/core/testing';
import { TimesheetComponent } from './tk-timesheet.component';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { of } from 'rxjs';
import { TkDataService } from '../tk-services/tk-data/tk-data.service';
describe('TimesheetComponent', async () => {
let dataService;
// tslint:disable-next-line: max-line-length
dataService = jasmine.createSpyObj('TkDataService', ['get', 'post', 'getUserId', 'getOpenPayPeriods', 'getChargeCodes', 'getUserRole', 'getuserdata']);
let component: TimesheetComponent;
let fixture: ComponentFixture<TimesheetComponent>;
beforeEach( async( () => {
TestBed.configureTestingModule({
declarations: [ TimesheetComponent ],
imports: [ HttpClientTestingModule ],
providers: [{ provide: TkDataService, useValue: dataService }]
})
.compileComponents()
}));
beforeEach(() => {
fixture = TestBed.createComponent(TimesheetComponent);
component = fixture.componentInstance;
});
it('should create component', () => {
expect(component).toBeTruthy();
});
it('should populate column headers with monday of the current week on initial view ', async(() => {
fixture.detectChanges();
let thisMonday = () => {
let date = new Date();
let day = date.getDay();
let diff = date.getDate() - day + (day == 0 ? -6 : 1); // adjust when day is sunday
let mon = new Date(date.setDate(diff));
return `${mon.getMonth() + 1}/${mon.getDate()}/${mon.getFullYear().toString().slice(-2)}`;
};
spyOn(component, 'getUserRole').and.returnValue(of({}));;
expect(component.weekDates[0]['date']).toEqual(null);
}));
TkDataservice-
import { environment } from 'src/environments/environment';
import { Injectable } from '@angular/core';
import { HttpClientModule, HttpClient, HttpHeaders, HttpResponse, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
import { OidcSecurityService } from 'angular-auth-oidc-client';
import { TimekardResponse } from 'src/app/tk-models/tk-response';
import { AuthService } from '../auth.service';
@Injectable({
providedIn: 'root'
})
export class TkDataService {
constructor(
private http: HttpClient
) {
}
post(route: string, data: any, responseType?){
if(localStorage.getItem('userRole') === null || localStorage.getItem('userRole') === undefined) {
this.getUserRole();
}
const observe = responseType === 'blob' ? 'response' : 'body';
let requestHeaders = new HttpHeaders();
requestHeaders = requestHeaders.set('Authorization', localStorage.getItem('bearerToken'));
// tslint:disable-next-line: max-line-length
return this.http.post<TimekardResponse>(environment.baseAPIUrl + route, data, {withCredentials: false, headers: requestHeaders, responseType, observe: observe as 'body'} );
}
}}
提前感谢您的帮助!
答案 0 :(得分:0)
您的代码组件不完整。我假设您调用getUserRole()的位置位于ngOnInit方法内。因此,如果是这样,则在测试中,必须先在夹具.detectChanges
之前定义spyOn。it('should populate column headers with monday of the current week on initial view ', async(() => {
spyOn(component, 'getUserRole').and.returnValue(of({}));
fixture.detectChanges();
let thisMonday = () => {
let date = new Date();
let day = date.getDay();
let diff = date.getDate() - day + (day == 0 ? -6 : 1); // adjust when day is sunday
let mon = new Date(date.setDate(diff));
return `${mon.getMonth() + 1}/${mon.getDate()}/${mon.getFullYear().toString().slice(-2)}`;
};
expect(component.weekDates[0]['date']).toEqual(null);
}));