Expected null to be 'Devin'.
LOG: Object{firstName: null, lastName: null, email: '', officeLocation: '', pathwaysControl: [], courses: [], skills: null}
export class EditTrainerComponent implements OnInit {
userId: number | undefined;
currentPage: string = '';
targetElementWidth: number = 0;
offices: OfficeLocation[] = [];
allCourses: Course[] = [];
courses: Course[] = [];
pathways: Pathway[] = [];
prevPathways: string[] = []; // remove me?
skills: Skill[] = [];
trainerForm!: FormGroup;
trainer: Trainer = emptyTrainer();
experienceExpand: string = 'out';
showModal: boolean = false;
constructor(
private formBuilder: FormBuilder,
private trainerService: TrainerService,
private officeLocationService: OfficeLocationService,
private courseService: CourseService,
private pathwayService: PathwayService,
private route: ActivatedRoute,
private router: Router,
private dialog: MatDialog,
private location: Location
) {
this.trainerForm = this.formBuilder.group({
firstName: [
null,
[
Validators.required,
Validators.minLength(2),
Validators.maxLength(12),
this.noBlankSpacesValidator,
],
],
lastName: [
null,
[
Validators.required,
Validators.minLength(2),
Validators.maxLength(12),
this.noBlankSpacesValidator,
],
],
email: [
'',
[
Validators.required,
Validators.pattern(
'^[a-zA-Z0-9._%+-]+@(?:[a-zA-Z0-9-]+.)?fdmgroup.com$'
),
],
[this.emailExistsValidator()],
],
officeLocation: ['', Validators.required],
pathwaysControl: [[]],
courses: [[]],
skills: [null, Validators.required],
});
}
ngOnInit(): void {
this.trainerService.getAllSkills().subscribe((skills) => {
this.skills = skills;
});
this.officeLocationService.getAllOfficeLocations().subscribe((offices) => {
this.offices = offices;
});
this.courseService.getAllCourses().subscribe((courses) => {
this.courses = courses;
this.allCourses = courses;
});
this.pathwayService.getAllPathways().subscribe((pathways) => {
this.pathways = pathways;
// Fetch the trainer that is being edited and populate fields
// This is inside getAllPathways because the ability to load pathways requires
// this.pathways to be loaded first
const trainerId = this.getTrainerId();
this.trainerService.getTrainerById(trainerId).subscribe((trainer) => {
this.trainer = trainer;
this.trainerForm.patchValue({
firstName: this.trainer.firstName,
lastName: this.trainer.lastName,
email: this.trainer.email,
officeLocation: this.trainer.officeLocation?.city,
pathwaysControl: this.getPathwaysByCourses(
this.trainer.coursesEligibleToTeach
),
courses: this.getCourseNames(this.trainer.coursesEligibleToTeach),
skills: this.getSkillNames(this.trainer.skills),
});
});
});
}
这是我的测试文件:
describe('EditTrainerComponent', () => {
let component: EditTrainerComponent;
let fixture: ComponentFixture<EditTrainerComponent>;
let mockTrainerService: jasmine.SpyObj<TrainerService>;
let mockCourseService: jasmine.SpyObj<CourseService>;
let mockPathwayService: jasmine.SpyObj<PathwayService>;
let locationSpy: SpyLocation;
let mockTrainer: Trainer;
let mockSkills: Skill[] = [];
let mockPathways: Pathway[] = [];
let mockCourses: Course[] = [];
beforeEach(async () => {
mockTrainer = {
userId: 14,
firstName: "Devin",
lastName: "Troy",
email: "[email protected]",
username: "devin.troy",
userType: {
userTypeId: 2,
name: "Trainer"
},
officeLocation: {
id: 5,
city: "Charlotte",
stateOrProvince: "NC",
country: {
countryId: 2,
countryName: "United States",
region: {
id: 1,
regionName: "North America",
regionCode: "NA"
},
countryCode: "USA"
}
},
dateJoined: new Date("2020-08-12T00:22:10.000+00:00"),
bio: "",
trainerStatus: "active",
trainerRoles: [],
coursesEligibleToTeach: [],
skills: [
{
id: 22,
name: "Excel"
},
{
id: 5,
name: "APM"
}
],
dateModified: new Date("2026-01-01T00:00:00.000+00:00")
};
mockSkills = [...]
mockPathways = [...]
mockCourses = [...]
mockTrainerService = jasmine.createSpyObj('TrainerService', [
'checkIfEmailExists',
'getAllSkills',
'getTrainerById'
]);
mockCourseService = jasmine.createSpyObj('CourseService', [
'getCoursesByPathwayId',
]);
mockPathwayService = jasmine.createSpyObj('PathwayService', [
'getAllPathways',
]);
mockCourseService.getCoursesByPathwayId.and.returnValue(of(mockCourses));
mockTrainerService.getAllSkills.and.returnValue(of(mockSkills));
mockTrainerService.checkIfEmailExists.and.returnValue(of(false));
mockPathwayService.getAllPathways.and.returnValue(of(mockPathways))
mockTrainerService.getTrainerById.and.returnValue(of(mockTrainer));
await TestBed.configureTestingModule({
declarations: [EditTrainerComponent],
imports: [
ReactiveFormsModule,
HttpClientTestingModule,
RouterModule.forRoot([]),
MatFormFieldModule,
MatInputModule,
MatSelectModule,
NoopAnimationsModule,
],
providers: [
{ provide: TrainerService, useValue: mockTrainerService },
{ provide: Location, useClass: SpyLocation },
],
}).compileComponents();
locationSpy = TestBed.inject(Location) as SpyLocation;
fixture = TestBed.createComponent(EditTrainerComponent);
component = fixture.componentInstance;
component.trainer = mockTrainer;
component.pathways = mockPathways;
component.courses = mockPathways[0].courses;
fixture.detectChanges();
});
// HERE IS MY TEST THAT IS FAILING:
fit('should show values for existing trainer', async() => {
mockTrainerService.getTrainerById.and.returnValue(of(mockTrainer));
fixture.detectChanges();
await fixture.whenStable();
expect(component.trainerForm).toBeDefined(); // passes
expect(component.trainerForm.controls['firstName']).toBeTruthy(); // passes
expect(component.pathways).toEqual(mockPathways); // passes
console.log(component.trainerForm.value) // logs obj with null values
expect(component.trainerForm.get('firstName')?.value).toBe(mockTrainer.firstName); // FAILS
});
fakeAsync
和
flush
来等待异步操作完成。您必须在测试用例中调用
ngOnInit
才能设置值。您可以删除
fixture.detectChanges()
并手动触发
ngOnInit
方法。
it('should show values for existing trainer', fakeAsync(() => {
mockPathwayService.getAllPathways.and.returnValue(of(mockPathways));
mockTrainerService.getTrainerById.and.returnValue(of(mockTrainer));
component.ngOnInit();
flush();
expect(component.trainerForm).toBeDefined(); // passes
expect(component.trainerForm.controls['firstName']).toBeTruthy(); // passes
expect(component.pathways).toEqual(mockPathways); // passes
console.log(component.trainerForm.value); // logs obj with null values
expect(component.trainerForm.get('firstName')?.value).toBe(
mockTrainer.firstName
); // FAILS
}));
完整代码:import {
TestBed,
ComponentFixture,
waitForAsync,
fakeAsync,
flush,
} from '@angular/core/testing';
import { AppComponent, PathwayService, TrainerService } from './app.component';
import { AppModule } from './app.module';
import { SpyLocation } from '@angular/common/testing';
import { of } from 'rxjs';
describe('EditTrainerComponent', () => {
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
let mockPathwayService: jasmine.SpyObj<PathwayService> = jasmine.createSpyObj(
'PathwayService',
['getAllPathways']
);
let mockTrainerService: jasmine.SpyObj<TrainerService> = jasmine.createSpyObj(
'TrainerService',
['getTrainerById']
);
let locationSpy: SpyLocation;
let mockTrainer: any = {
userId: 14,
firstName: 'Devin',
lastName: 'Troy',
email: '[email protected]',
username: 'devin.troy',
userType: {
userTypeId: 2,
name: 'Trainer',
},
officeLocation: {
id: 5,
city: 'Charlotte',
stateOrProvince: 'NC',
country: {
countryId: 2,
countryName: 'United States',
region: {
id: 1,
regionName: 'North America',
regionCode: 'NA',
},
countryCode: 'USA',
},
},
dateJoined: new Date('2020-08-12T00:22:10.000+00:00'),
bio: '',
trainerStatus: 'active',
trainerRoles: [],
coursesEligibleToTeach: [],
skills: [
{
id: 22,
name: 'Excel',
},
{
id: 5,
name: 'APM',
},
],
dateModified: new Date('2026-01-01T00:00:00.000+00:00'),
};
let mockSkills: any[] = [];
let mockPathways: any[] = [];
let mockCourses: any[] = [];
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [AppComponent],
imports: [],
providers: [
{ provide: TrainerService, useValue: mockTrainerService },
{ provide: PathwayService, useValue: mockPathwayService },
{ provide: Location, useClass: SpyLocation },
],
}).compileComponents();
// locationSpy = TestBed.inject(Location) as SpyLocation;
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
});
// HERE IS MY TEST THAT IS FAILING:
it('should show values for existing trainer', fakeAsync(() => {
mockPathwayService.getAllPathways.and.returnValue(of(mockPathways));
mockTrainerService.getTrainerById.and.returnValue(of(mockTrainer));
component.ngOnInit();
flush();
expect(component.trainerForm).toBeDefined(); // passes
expect(component.trainerForm.controls['firstName']).toBeTruthy(); // passes
expect(component.pathways).toEqual(mockPathways); // passes
console.log(component.trainerForm.value); // logs obj with null values
expect(component.trainerForm.get('firstName')?.value).toBe(
mockTrainer.firstName
); // FAILS
}));
});