Eno*_*noy 5 javascript unit-testing jasmine angular
您好,感谢您的宝贵时间!
我正在学习如何使用Angular,并且对学习如何测试其组件感兴趣。
目前,我正在苦苦挣扎,因为我已经完成了Angular页面的“英雄之旅”教程,并且正在测试代码以更好地理解它。
关键是我正在测试hero-details组件,其代码为:
import {Component, OnInit, Input} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {MyHeroService} from '../hero-service/my-hero.service';
import {Location} from '@angular/common';
import {Hero} from '../Hero';
@Component({
selector: 'app-hero-details',
templateUrl: './hero-details.component.html',
styleUrls: ['./hero-details.component.css']
})
export class HeroDetailsComponent implements OnInit {
@Input() hero: Hero;
constructor(private route: ActivatedRoute,
private myHeroService: MyHeroService,
private location: Location) {
}
ngOnInit(): void {
this.getHero();
}
getHero(): void {
const id = +this.route.snapshot.paramMap.get('id');
this.myHeroService.getHero(id)
.subscribe(hero => this.hero = hero);
}
goBack(): void {
this.location.back();
}
}
Run Code Online (Sandbox Code Playgroud)
我的测试试图证明在创建hero-details组件后调用了getHero():
import {HeroDetailsComponent} from './hero-details.component';
import {ActivatedRoute} from '@angular/router';
import {MyHeroService} from '../hero-service/my-hero.service';
import {MessageService} from '../message.service';
import {Location} from '@angular/common';
import {provideLocationStrategy} from '@angular/router/src/router_module';
import {BrowserPlatformLocation} from '@angular/platform-browser/src/browser/location/browser_platform_location';
describe('heroDetails', () => {
it('should call getHero after being created', () => {
const heroDetailsComponent = new HeroDetailsComponent(new ActivatedRoute(),
new MyHeroService(new MessageService([])),
new Location(provideLocationStrategy(new BrowserPlatformLocation(['anyParameter']), '/')));
spyOn(heroDetailsComponent, 'getHero');
heroDetailsComponent.ngOnInit();
expect(heroDetailsComponent.getHero()).toHaveBeenCalled();
});
});
Run Code Online (Sandbox Code Playgroud)
我面临的困难是当我尝试创建一个新位置时,这是Hero-datail组件的构造函数的必需参数。
第一个Location的参数是PlatformStrategy,因此我使用了提供程序来构建它。另外,提供程序还需要一个PlatformLocation(),它看起来像是抽象的,所以我选择了唯一可以找到的实现,即BrowserPlatformLocation。
奇怪的是,IDE确实找到了那些模块,因为我可以导航到它们。
另外,如果我注释掉该测试,该套件也可以正常工作:
另外,我也读过:
我该如何以正确的方式进行测试?在哪里可以找到有关正确进行此类测试的更多信息?该测试如何轻松模拟该Location参数?
谢谢您阅读此篇
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ HeroDetailsComponent ],
providers: [ MyHeroService ],
imports: [ RouterTestingModule ],
providers: [{ provide: Location, useClass: SpyLocation }]
})
.compileComponents();
}));
it('should logout from application', async(() => {
const location: Location = TestBed.get(Location);
expect(location.href).toContain('blablabla url');
}));
Run Code Online (Sandbox Code Playgroud)
使用来自@angular/router/testing 的 SpyLocation
Location 是内置服务,您无需实例化它,只需对其进行模拟即可:
const locationStub = {
back: jasmine.createSpy('back')
}
Run Code Online (Sandbox Code Playgroud)
然后在您的providers数组中:
providers: [ ..., {provide: Location, useValue: locationStub} ],
Run Code Online (Sandbox Code Playgroud)
然后在您的测试中,只需调用components goBack方法,然后使用Injector即可获取服务存根的实例,如下所示:
const location = fixture.debugElement.injector.get(Location);
Run Code Online (Sandbox Code Playgroud)
然后测试一下,该back函数已被调用:
expect(location.back).toHaveBeenCalled();
Run Code Online (Sandbox Code Playgroud)
这应该可以解决问题。据我所知,这是处理内置服务的最佳方法,您无需测试它们(Angular团队已经做到了),只需对其进行模拟并确保已正确调用它们即可。
小智 3
如果我是您,我不会费心从头开始创建测试:CLI 创建预制测试。
在这些测试中,有一个 TestBed,用于设置测试模块来测试您的组件。如果你使用它,你只需要导入一个路由器测试模块。
这会给出这样的结果:
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ HeroDetailsComponent ],
providers: [ MyHeroService ],
imports: [ RouterTestingModule ]
})
.compileComponents();
}));
Run Code Online (Sandbox Code Playgroud)
就这样,你的整个路由策略就被嘲笑了。
| 归档时间: |
|
| 查看次数: |
2685 次 |
| 最近记录: |