Angular 单元测试 ngOnInit 订阅
Angular unit test ngOnInit subscription
我开始使用 Jasmine 在 Angular 9 中进行单元测试。
我正在测试一个实现 ngOnInit
:
的简单组件
export class HomeComponent implements OnInit {
constructor(private router: Router
, private authenticationService: AuthenticationService) { }
ngOnInit(): void {
this.authenticationService.checkIsAuthenticatedObservable()
.subscribe(
(isAuthenicated: boolean) => {
if (isAuthenicated === true) {
this.router.navigate(['/observation-feed']);
}
});
}
}
我在执行 ngOnInIt 生命周期挂钩时遇到错误:
TypeError: Cannot read property 'subscribe' of undefined
at <Jasmine>
at HomeComponent.ngOnInit (http://localhost:9876/_karma_webpack_/main.js:8140:13)
我的测试规范是这样设置的:
describe('HomeComponent', () => {
let component: HomeComponent;
let fixture: ComponentFixture<HomeComponent>;
let router: Router;
let mockAuthenticationService;
beforeEach(async(() => {
mockAuthenticationService = jasmine.createSpyObj(['checkIsAuthenticatedObservable']);
TestBed.configureTestingModule({
imports: [
RouterTestingModule.withRoutes([
// { path: 'login', component: DummyLoginLayoutComponent },
])
],
declarations: [ HomeComponent ],
providers: [
{ provide: AuthenticationService, useValue: mockAuthenticationService }
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(HomeComponent);
router = TestBed.get(Router);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
mockAuthenticationService.checkIsAuthenticatedObservable.and.returnValue(of(false));
fixture.detectChanges();
// component.ngOnInit();
expect(component).toBeTruthy();
});
});
我尝试了设置模拟对象的各种组合,并在初始化的不同点调用 fixture.detectChanges();
和 component.ngOnInit();
。 None 我尝试过的方法都有效。这里出了什么问题?
当您在 beforeEach
部分调用 fixture.detectChanges
时,Angular 运行生命周期挂钩并调用 ngOnInit
。这就是为什么你会出错 - 你在测试中模拟 checkIsAuthenticatedObservable
,在第一个 fixture.detectChanges
之后。
将模拟移动到 beforeEach
部分,在 fixture.detectChanges
之前,它将正常工作。
此外,对于 Angular 9,您应该使用 TestBed.inject
而不是现在已弃用的 TestBed.get
。
beforeEach(() => {
fixture = TestBed.createComponent(HomeComponent);
router = TestBed.inject(Router);
component = fixture.componentInstance;
mockAuthenticationService.checkIsAuthenticatedObservable.and.returnValue(of(false));
fixture.detectChanges();
});
it('should create', () => {
fixture.detectChanges();
expect(component).toBeTruthy();
});
我开始使用 Jasmine 在 Angular 9 中进行单元测试。
我正在测试一个实现 ngOnInit
:
export class HomeComponent implements OnInit {
constructor(private router: Router
, private authenticationService: AuthenticationService) { }
ngOnInit(): void {
this.authenticationService.checkIsAuthenticatedObservable()
.subscribe(
(isAuthenicated: boolean) => {
if (isAuthenicated === true) {
this.router.navigate(['/observation-feed']);
}
});
}
}
我在执行 ngOnInIt 生命周期挂钩时遇到错误:
TypeError: Cannot read property 'subscribe' of undefined
at <Jasmine>
at HomeComponent.ngOnInit (http://localhost:9876/_karma_webpack_/main.js:8140:13)
我的测试规范是这样设置的:
describe('HomeComponent', () => {
let component: HomeComponent;
let fixture: ComponentFixture<HomeComponent>;
let router: Router;
let mockAuthenticationService;
beforeEach(async(() => {
mockAuthenticationService = jasmine.createSpyObj(['checkIsAuthenticatedObservable']);
TestBed.configureTestingModule({
imports: [
RouterTestingModule.withRoutes([
// { path: 'login', component: DummyLoginLayoutComponent },
])
],
declarations: [ HomeComponent ],
providers: [
{ provide: AuthenticationService, useValue: mockAuthenticationService }
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(HomeComponent);
router = TestBed.get(Router);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
mockAuthenticationService.checkIsAuthenticatedObservable.and.returnValue(of(false));
fixture.detectChanges();
// component.ngOnInit();
expect(component).toBeTruthy();
});
});
我尝试了设置模拟对象的各种组合,并在初始化的不同点调用 fixture.detectChanges();
和 component.ngOnInit();
。 None 我尝试过的方法都有效。这里出了什么问题?
当您在 beforeEach
部分调用 fixture.detectChanges
时,Angular 运行生命周期挂钩并调用 ngOnInit
。这就是为什么你会出错 - 你在测试中模拟 checkIsAuthenticatedObservable
,在第一个 fixture.detectChanges
之后。
将模拟移动到 beforeEach
部分,在 fixture.detectChanges
之前,它将正常工作。
此外,对于 Angular 9,您应该使用 TestBed.inject
而不是现在已弃用的 TestBed.get
。
beforeEach(() => {
fixture = TestBed.createComponent(HomeComponent);
router = TestBed.inject(Router);
component = fixture.componentInstance;
mockAuthenticationService.checkIsAuthenticatedObservable.and.returnValue(of(false));
fixture.detectChanges();
});
it('should create', () => {
fixture.detectChanges();
expect(component).toBeTruthy();
});