kri*_*nya 1 unit-testing typescript angular
如标题所示,我需要router.events在单元测试中进行模拟。
在我的组件中,我做了一些正则表达式来获取url中斜线之间的文本的第一个实例;例如,/pdp/
constructor(
private route: ActivatedRoute,
private router: Router,
}
this.router.events.pipe(takeUntil(this.ngUnsubscribe$))
.subscribe(route => {
if (route instanceof NavigationEnd) {
// debugger
this.projectType = route.url.match(/[a-z-]+/)[0];
}
});
Run Code Online (Sandbox Code Playgroud)
构建组件时,我的单元测试出错误:Cannot read property '0' of null。当我在调试器中添加注释时,route似乎没有正确设置,但是我在单元测试中对其进行了设置。我已经通过几种不同的方式完成了此工作(受本篇文章的启发:模拟router.events.subscribe()Angular2等)。
第一次尝试:
providers: [
{
provide: Router,
useValue: {
events: of(new NavigationEnd(0, '/pdp/project-details/4/edit', 'pdp/project-details/4/edit'))
}
},
// ActivatedRoute also being mocked
{
provide: ActivatedRoute,
useValue: {
snapshot: { url: [{ path: 'new' }, { path: 'edit' }] },
parent: {
parent: {
snapshot: {
url: [
{ path: 'pdp' }
]
}
}
}
}
}
]
Run Code Online (Sandbox Code Playgroud)
第二次尝试(基于以上帖子):
class MockRouter {
public events = of(new NavigationEnd(0, '/pdp/project-details/4/edit', '/pdp/project-details/4/edit'))
}
providers: [
{
provide: Router,
useClass: MockRouter
}
]
Run Code Online (Sandbox Code Playgroud)
第三次尝试(也基于以上帖子):
class MockRouter {
public ne = new NavigationEnd(0, '/pdp/project-details/4/edit', '/pdp/project-details/4/edit');
public events = new Observable(observer => {
observer.next(this.ne);
observer.complete();
});
}
providers: [
{
provide: Router,
useClass: MockRouter
}
]
Run Code Online (Sandbox Code Playgroud)
第四次尝试:
beforeEach(() => {
spyOn((<any>component).router, 'events').and.returnValue(of(new NavigationEnd(0, '/pdp/project-details/4/edit', 'pdp/project-details/4/edit')))
...
Run Code Online (Sandbox Code Playgroud)
第五次尝试:
beforeEach(() => {
spyOn(TestBed.get(Router), 'events').and.returnValue(of({ url:'/pdp/project-details/4/edit' }))
...
Run Code Online (Sandbox Code Playgroud)
在以上所有情况下,route均未设置;该NavigationEnd对象等于:
{ id: 1, url: "/", urlAfterRedirects: "/" }
Run Code Online (Sandbox Code Playgroud)
有什么想法吗?
这是我想出的答案。我想我只是没有将第一种方法扩展到足够远:
import { of } from 'rxjs';
import { NavigationEnd, Router } from '@angular/router';
providers: [
{
provide: Router,
useValue: {
url: '/non-pdp/phases/8',
events: of(new NavigationEnd(0, 'http://localhost:4200/#/non-pdp/phases/8', 'http://localhost:4200/#/non-pdp/phases/8')),
navigate: jasmine.createSpy('navigate')
}
}
]
Run Code Online (Sandbox Code Playgroud)
它可以很简单:
TestBed.configureTestingModule({
imports: [RouterTestingModule]
}).compileComponents()
...
const event = new NavigationEnd(42, '/', '/');
TestBed.get(Router).events.next(event);
Run Code Online (Sandbox Code Playgroud)
认为这可能会有所帮助...在模板中使用带有 routerLinks 的页脚组件。收到未提供根的错误...必须使用“真正的”路由器...但有一个间谍变量...并将 router.events 指向我的测试可观察值,以便我可以控制导航事件
export type Spied<T> = { [Method in keyof T]: jasmine.Spy };
describe("FooterComponent", () => {
let component: FooterComponent;
let fixture: ComponentFixture<FooterComponent>;
let de: DebugElement;
const routerEvent$ = new BehaviorSubject<RouterEvent>(null);
let router: Spied<Router>;
beforeEach(async(() => {
TestBed.configureTestingModule({
providers: [provideMock(SomeService), provideMock(SomeOtherService)],
declarations: [FooterComponent],
imports: [RouterTestingModule]
}).compileComponents();
router = TestBed.get(Router);
(<any>router).events = routerEvent$.asObservable();
fixture = TestBed.createComponent(FooterComponent);
component = fixture.componentInstance;
de = fixture.debugElement;
}));
// component subscribes to router nav event...checking url to hide/show a link
it("should return false for showSomeLink()", () => {
routerEvent$.next(new NavigationEnd(1, "/someroute", "/"));
component.ngOnInit();
expect(component.showSomeLink()).toBeFalsy();
fixture.detectChanges();
const htmlComponent = de.query(By.css("#someLinkId"));
expect(htmlComponent).toBeNull();
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3497 次 |
| 最近记录: |