Search code examples
angularjsunit-testingangularjs-service

Mocking a service thats provided in a component controller in a unit test


This is the error I'm seeing when trying to run my unit test ..

Expected undefined to be defined.
TypeError: undefined is not an object (evaluating '$rootScope.$digest')

Module 'ThirdPartyModule' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.

Any ideas how to mock the testService so that I can still compile my component?

test.component.spec.ts

import { TestModule } from '../index';

describe('Component: testComponent', () => {

  let $rootScope: angular.IScope;
  let element: angular.IAugmentedJQuery;

  beforeEach(() => {
    angular.mock.module('ui.router');
    angular.mock.module(TestModule.name);
  });

  beforeEach(inject((
    _$rootScope_: angular.IScope,
    $compile: angular.ICompileService,
    _$state_: angular.ui.IStateService) => {
    $rootScope = _$rootScope_;
    element = angular.element('<test></test>');
    element = $compile(element)($rootScope);
  }));

  it('should verify component compiled and rendered template', () => {
    expect(element).toBeDefined();
    $rootScope.$digest();
    let link = element.find('a');
    expect(link.text()).toContain('Click this link!');
  });
});

test.module.ts

import { TestComponent } from './test';

export let TestModule: ng.IModule = angular.module(
  'test', // my module name
  ['ui.router', 'ThirdPartyModule']) // dependencies, ThirdPartyModule contains testService
  .component('test', new TestComponent());

test.component.ts

import { TestComponentController } from './test.component.controller';

export class TestComponent implements ng.IComponentOptions {
  public template: string = '<a ng-if="ctrl.serviceReturned">Click this link!</a>';
  public controller: Function = TestComponentController;
  public controllerAs: string = 'ctrl';

  constructor() {}
}

test.component.controller.ts

export class TestComponentController {

  public serviceReturned: boolean = false;

  constructor(private testService: any) {
    if (this.testService.isDone()) {
      this.serviceReturned = true;
    }
  }
}

TestComponentController.$inject = ['testService'];

Solution

  • Don't you need to add 'ThirdPartyModule' in an angular.mock.module?