1

I have a route guard that uses a util function.

This looks like

import { Injectable } from '@angular/core';
import { CanActivateChild, ActivatedRouteSnapshot } from '@angular/router';

import { AuthService } from '../../services';

import { Observable } from 'rxjs';

import objectFromHash from '../../utils/object-from-hash/object-from-hash.util';

@Injectable()
export default class AuthGuard implements CanActivateChild {
  constructor(private authService: AuthService) {}

  canActivateChild(route: ActivatedRouteSnapshot): Observable<boolean> {
    let hasValidSession: Observable<boolean>;

    const { id_token, access_token } = objectFromHash(route.fragment);

    hasValidSession = this.authService.isSessionValid(id_token, access_token);

    return hasValidSession;
  }
}

I am currently trying to test this using Jasmine - however I am unsure how I can mock out the objectFromHash util function.

I would like to test that this function is called during the execution of my route guard.

My spec file looks like this

import { TestBed } from '@angular/core/testing';
import AuthGuard from './auth.guard';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { AuthService } from '../../services';

describe('AuthGuard', () => {
  it('should pass the route hash to a util method', () => {
    const { authGuard } = setup();

      // I AM UNSURE WHAT TO DO HERE?
  });

  const setup = () => {
    TestBed.configureTestingModule({
      providers: [
        AuthGuard,
        {
          provide: AuthService,
          useClass: MockAuthService,
        },
      ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA],
    }).compileComponents();

    const authGuard = TestBed.get(AuthGuard);
    const authService = TestBed.get(AuthService);
    const objectFromHash = TestBed.get(objectFromHash);

    return { authGuard, authService };
  };
});

const MOCK_TOKEN = '';

export class MockAuthService {
  isSessionValid(id_token?: string, access_token?: string) {}
}

Attempting to access objectFromHash returns an error reading

​​TypeError: Cannot read property 'ngInjectableDef' of undefined​​

1 Answer 1

2

I was able to achieve this by importing the util and spying on it.

As the util is a default export I did have to do this spyOn(helper, 'default')

import { TestBed } from '@angular/core/testing'; 
import AuthGuard from './auth.guard';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { AuthService } from '../../services';

import * as helper from '../../utils/object-from-hash/object-from-hash.util';

describe('AuthGuard', () => {
  it('should pass the route hash to a util method', () => {
    const { authGuard, props } = setup({});
    const objectFromHashSpy = spyOn(helper, 'default').and.returnValue({
      id_token: 'foo',
      access_token: 'bar',
    });

    authGuard.canActivateChild(props);

    expect(objectFromHashSpy).toHaveBeenCalled();
  });

  const setup = propOverrides => {
    TestBed.configureTestingModule({
      providers: [
        AuthGuard,
        {
          provide: AuthService,
          useClass: MockAuthService,
        },
      ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA],
    }).compileComponents();

    const props = Object.assign({ fragment: null }, { ...propOverrides });

    const authGuard = TestBed.get(AuthGuard);
    const authService = TestBed.get(AuthService);

    return { authGuard, props, authService };
  };
});

const MOCK_ROUTE_FRAGMENT = '';

export class MockAuthService {
  isSessionValid(id_token?: string, access_token?: string) {}
}
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.