puddlejumper26 / blogs

Personal Tech Blogs
4 stars 1 forks source link

ActivatedRoute, serviceSpy, routerSpy in Angular Testing #35

Open puddlejumper26 opened 4 years ago

puddlejumper26 commented 4 years ago

ActivatedRoute normally used together with service,

it passes data through URL to the UI, take the interface here as references.

interface ActivatedRoute {
  snapshot: ActivatedRouteSnapshot
  url: Observable<UrlSegment[]>
  params: Observable<Params>
  queryParams: Observable<Params>
  fragment: Observable<string>
  data: Observable<Data>
  outlet: string
  component: Type<any> | string | null
  routeConfig: Route | null
  root: ActivatedRoute
  parent: ActivatedRoute | null
  firstChild: ActivatedRoute | null
  children: ActivatedRoute[]
  pathFromRoot: ActivatedRoute[]
  paramMap: Observable<ParamMap>
  queryParamMap: Observable<ParamMap>
  toString(): string
}

1

Therefore in the test, we need to create the mockActivatedRoute here the targetVariable, targetVariableRate are the actual variables called by the service through the ActivatedRoute, and here the activatedRouted is activated through the sampleId . Here the sampleDATADto is the data interface adopted inside the sampleService.

const TEST_DATA: sampleDATADto[] = [
     {
           sampleVariable: 20,
           sampleVariableRate: 0.2,
     }
]

describr( '...', ( ) => {
    const mockActivatedRoute = {
      data: of<data>({
            someId: 'sampleId',
      }),
  };
}) 

2

then it needs to be added into the provides, cause the mockActivatedRoute replaces ActivatedRoute in this test, added inside the beforeEach, after the imports

imports: [ ... ],
providers: [
                {
                    provide: ActivatedRoute,
                    useValue: mockActivatedRoute,
                },
]

3

we need to create a spy, to spy on the activity of the service, or if we need the router for the navigation, then we create a routerSpy.

3.1

routerSpy = jasmine.createSpyObj('Router', ['navigate']);
expect(routerSpy.navigate).toHaveBeenCalledWith([
         ...  // here should be identical with the date inside the component.ts 
     ], {
        relativeTo: mockActicatedRoute, // depends whether there is such statement inside component.ts
});

3.2

let sampleServiceSpy: jasmine.SpyObj<SampleService>;

    beforeEach(async(() => {
        sampleServiceSpy= jasmine.createSpyObj('SampleService', ['sampleMethodInsideSampleService']);

        sampleServiceSpy.sampleMethodInsideSampleService.and.returnValue(of(TEST_DATA));
        const mockActivatedRoute = {
                  data: of<data>({
                         someId: 'sampleId',
        }),
  };