Home:ALL Converter>Angular Mock ActivatedRoute using Snapshot and ParamMap

Angular Mock ActivatedRoute using Snapshot and ParamMap

Ask Time:2018-04-19T17:32:50         Author:ismaestro

Json Formatter

I'm using this, from here:

constructor(private heroService: HeroService,
    private activatedRoute: ActivatedRoute) {
}

ngOnInit() {
    const heroId = this.activatedRoute.snapshot.paramMap.get('id');
    this.heroService.getHeroById(heroId).subscribe((hero: Hero) => {
        ...
    });
}

Now I have a unit test that needs to mock this ActivatedRoute. I've already check some answers here in stackoverflow but without luck.

Notice that I'm using snapshot.paramMap so many solutions do not work at all. For example, this, this, and this do not work.

I think the near valid answer could be:

{
    provide: ActivatedRoute,
    useValue: {paramMap: Observable.of(convertToParamMap({id: 1}))}
}

But does not work either.

The error showing is:

Error: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'ng:///HeroesModule/HeroDetailComponent_Host.ngfactory.js'.
    error properties: Object({ INDEX_SIZE_ERR: 1, DOMSTRING_SIZE_ERR: 2, HIERARCHY_REQUEST_ERR: 3, WRONG_DOCUMENT_ERR: 4, INVALID_CHARACTER_ERR: 5, NO_DATA_ALLOWED_ERR: 6, NO_MODIFICATION_ALLOWED_ERR: 7, NOT_FOUND_ERR: 8, NOT_SUPPORTED_ERR: 9, INUSE_ATTRIBUTE_ERR: 10, INVALID_STATE_ERR: 11, SYNTAX_ERR: 12, INVALID_MODIFICATION_ERR: 13, NAMESPACE_ERR: 14, INVALID_ACCESS_ERR: 15, VALIDATION_ERR: 16, TYPE_MISMATCH_ERR: 17, SECURITY_ERR: 18, NETWORK_ERR: 19, ABORT_ERR: 20, URL_MISMATCH_ERR: 21, QUOTA_EXCEEDED_ERR: 22, TIMEOUT_ERR: 23, INVALID_NODE_TYPE_ERR: 24, DATA_CLONE_ERR: 25, code: 19 })

This is because I'm doing a request that responses with status 500 because paramMap is undefined so there is no id on the request.

... any ideas?

Thanks and BR

Author:ismaestro,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/49917588/angular-mock-activatedroute-using-snapshot-and-parammap
Ibrahim El_Khatib :

Add snapshot to the useValue like:\n\n{\n provide: ActivatedRoute,\n useValue: {\n snapshot: {\n paramMap: convertToParamMap({\n id: '1'\n })\n }\n }\n }\n",
2018-04-19T12:25:05
Stephen G Tuggy :

In recent Angular versions, a project's aot setting is on by default (for better compile-time type checking). If this is the case with your project, then you probably need to at least stub out all the properties of ActivatedRoute and ActivatedRouteSnapshot. Something like this:\nimport { async, ComponentFixture, TestBed } from '@angular/core/testing';\nimport { Type } from '@angular/core';\nimport { Location } from '@angular/common';\nimport { MockPlatformLocation } from '@angular/common/testing';\nimport { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';\nimport { ActivatedRoute, ActivatedRouteSnapshot, Params, ParamMap, convertToParamMap } from '@angular/router';\nimport { of, BehaviorSubject } from 'rxjs';\n\nimport { HeroDetailComponent } from './hero-detail.component';\nimport { Hero } from '../hero';\n\n\nexport class MockActivatedRouteSnapshot implements ActivatedRouteSnapshot {\n private innerTestParams?: Params;\n\n constructor(params?: Params) {\n if (params) {\n this.testParams = params;\n } else {\n this.testParams = null;\n }\n }\n\n private get testParams() {\n return this.innerTestParams;\n }\n\n private set testParams(params: Params) {\n this.innerTestParams = params;\n }\n\n get paramMap() {\n return convertToParamMap(this.testParams);\n }\n\n get queryParamMap() {\n return this.paramMap;\n }\n\n get url() {\n return null;\n }\n\n get fragment() {\n return null;\n }\n\n get data() {\n return null;\n }\n\n get outlet() {\n return null;\n }\n\n get params() {\n return this.innerTestParams;\n }\n\n get queryParams() {\n return this.innerTestParams;\n }\n\n get component() {\n return null;\n }\n\n get routeConfig() {\n return null;\n }\n\n get root() {\n return null;\n }\n\n get parent() {\n return null;\n }\n\n get firstChild() {\n return null;\n }\n\n get children() {\n return null;\n }\n\n get pathFromRoot() {\n return null;\n }\n}\n\n\nexport class MockActivatedRoute implements ActivatedRoute {\n private innerTestParams?: Params;\n private subject?: BehaviorSubject<Params> = new BehaviorSubject(this.testParams);\n private paramMapSubject?: BehaviorSubject<ParamMap> = new BehaviorSubject(convertToParamMap(this.testParams));\n\n constructor(params?: Params) {\n if (params) {\n this.testParams = params;\n } else {\n this.testParams = null;\n }\n }\n\n private get testParams() {\n return this.innerTestParams;\n }\n\n private set testParams(params: Params) {\n this.innerTestParams = params;\n this.subject.next(params);\n this.paramMapSubject.next(convertToParamMap(params));\n }\n\n get snapshot() {\n return new MockActivatedRouteSnapshot(this.testParams);\n }\n\n get params() {\n return this.subject.asObservable();\n }\n\n get queryParams() {\n return this.params;\n }\n\n get paramMap() {\n return this.paramMapSubject.asObservable();\n }\n\n get queryParamMap() {\n return this.paramMap;\n }\n\n get url() {\n return null;\n }\n\n get fragment() {\n return null;\n }\n\n get data() {\n return null;\n }\n\n get outlet() {\n return null;\n }\n\n get component() {\n return null;\n }\n\n get routeConfig() {\n return null;\n }\n\n get root() {\n return null;\n }\n\n get parent() {\n return null;\n }\n\n get firstChild() {\n return null;\n }\n\n get children() {\n return null;\n }\n\n get pathFromRoot() {\n return null;\n }\n}\n\n\ndescribe('HeroDetailComponent', () => {\n let component: HeroDetailComponent;\n let fixture: ComponentFixture<HeroDetailComponent>;\n let httpMock: HttpTestingController;\n let routeMock: MockActivatedRoute;\n let initialMockParams: Params;\n let locationMock: MockPlatformLocation;\n\n beforeEach(async(() => {\n initialMockParams = {id: 11};\n routeMock = new MockActivatedRoute(initialMockParams);\n locationMock = new MockPlatformLocation;\n TestBed.configureTestingModule({\n imports: [\n HttpClientTestingModule\n ],\n declarations: [ HeroDetailComponent ],\n providers: [\n {\n provide: ActivatedRoute, useValue: routeMock,\n },\n {\n provide: Location, useValue: locationMock,\n }\n ]\n })\n .compileComponents();\n }));\n\n beforeEach(() => {\n fixture = TestBed.createComponent(HeroDetailComponent);\n component = fixture.componentInstance;\n httpMock = TestBed.inject<HttpTestingController>(HttpTestingController as Type<HttpTestingController>);\n fixture.detectChanges();\n });\n\n afterEach(() => {\n httpMock.verify();\n });\n\n it('should be created', () => {\n fixture.detectChanges();\n\n expect(component).toBeTruthy();\n\n const dummyHero: Hero = { id: 11, name: 'dummyHero' };\n const req = httpMock.expectOne('api/details/11');\n req.flush(dummyHero);\n });\n});\n",
2020-08-14T14:22:35
yy