or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

angularjs-integration.mdcomponent-bridging.mddynamic-upgrade.mdindex.mdservice-integration.mdstatic-upgrade.mdtesting-utilities.md
tile.json

testing-utilities.mddocs/

Testing Utilities

Testing utilities provide helper functions for unit testing hybrid applications with mixed Angular and AngularJS dependencies, enabling comprehensive test coverage during migration.

Capabilities

Angular Testing Module for AngularJS Dependencies

Create Angular testing modules that can inject upgraded AngularJS services.

/**
 * Creates an Angular testing module that provides access to AngularJS services
 * @param angularJSModules - Array of AngularJS module names to load
 * @param strictDi - Whether to enable AngularJS strict dependency injection
 * @returns Angular NgModule class for testing
 */
function createAngularTestingModule(
  angularJSModules: string[],
  strictDi?: boolean
): Type<any>;

Usage Example:

import { TestBed } from "@angular/core/testing";
import { createAngularTestingModule } from "@angular/upgrade/static/testing";
import { MyAngularService } from "./my-angular.service";

describe("MyAngularService", () => {
  let service: MyAngularService;
  
  beforeEach(() => {
    // Create testing module with AngularJS dependencies
    const AngularJSTestingModule = createAngularTestingModule([
      "myAngularJSModule"
    ], true);
    
    TestBed.configureTestingModule({
      imports: [AngularJSTestingModule],
      providers: [MyAngularService]
    });
    
    service = TestBed.inject(MyAngularService);
  });
  
  it("should interact with AngularJS services", () => {
    // Test Angular service that depends on AngularJS services
    const result = service.processWithAngularJSService("test data");
    expect(result).toBeDefined();
  });
});

AngularJS Testing Module for Angular Dependencies

Create AngularJS testing modules that can inject downgraded Angular services.

/**
 * Creates an AngularJS testing module that provides access to Angular services
 * @param angularModules - Array of Angular modules to include
 * @returns AngularJS module name for testing
 */
function createAngularJSTestingModule(angularModules: any[]): string;

Usage Example:

import { Injectable } from "@angular/core";
import { createAngularJSTestingModule } from "@angular/upgrade/static/testing";

// Angular service to test
@Injectable()
export class DataService {
  getData(): string[] {
    return ["item1", "item2", "item3"];
  }
}

// AngularJS test setup
describe("AngularJS Controller with Angular Dependencies", () => {
  let $controller: any;
  let $rootScope: any;
  let dataService: any;
  
  beforeEach(() => {
    // Create AngularJS testing module with Angular dependencies
    const testingModuleName = createAngularJSTestingModule([{
      providers: [DataService]
    }]);
    
    // Load testing module and your app module
    angular.mock.module(testingModuleName);
    angular.mock.module("myApp");
    
    angular.mock.inject((_$controller_: any, _$rootScope_: any, _dataService_: any) => {
      $controller = _$controller_;
      $rootScope = _$rootScope_;
      dataService = _dataService_;
    });
  });
  
  it("should use Angular service in AngularJS controller", () => {
    const scope = $rootScope.$new();
    const ctrl = $controller("MyController", { $scope: scope, dataService });
    
    expect(ctrl.items).toEqual(["item1", "item2", "item3"]);
  });
});

Complete Test Setup Example

Comprehensive testing setup for a hybrid application:

import { TestBed } from "@angular/core/testing";
import { NgModule, Injectable } from "@angular/core";
import { createAngularTestingModule, createAngularJSTestingModule } from "@angular/upgrade/static/testing";
import { downgradeInjectable } from "@angular/upgrade/static";

// Angular service
@Injectable()
export class UserService {
  getUsers(): any[] {
    return [
      { id: 1, name: "John" },
      { id: 2, name: "Jane" }
    ];
  }
}

// AngularJS service
function legacyDataService() {
  return {
    processData: function(data: any[]) {
      return data.map(item => ({ ...item, processed: true }));
    }
  };
}

describe("Hybrid Application Testing", () => {
  describe("Angular Component Tests", () => {
    beforeEach(() => {
      // Test Angular components that use AngularJS services
      angular.module("testAngularJSModule", [])
        .service("legacyDataService", legacyDataService);
      
      const AngularJSTestingModule = createAngularTestingModule([
        "testAngularJSModule"
      ]);
      
      TestBed.configureTestingModule({
        imports: [AngularJSTestingModule],
        providers: [UserService]
      });
    });
    
    it("should test Angular service with AngularJS dependencies", () => {
      const userService = TestBed.inject(UserService);
      const users = userService.getUsers();
      
      expect(users).toHaveLength(2);
      expect(users[0].name).toBe("John");
    });
  });
  
  describe("AngularJS Component Tests", () => {
    beforeEach(() => {
      // Test AngularJS components that use Angular services
      @NgModule({
        providers: [UserService]
      })
      class TestModule {}
      
      const testingModuleName = createAngularJSTestingModule([TestModule]);
      
      // Create AngularJS module with downgraded Angular services
      angular.module("testApp", [])
        .factory("userService", downgradeInjectable(UserService))
        .service("legacyDataService", legacyDataService);
      
      angular.mock.module(testingModuleName);
      angular.mock.module("testApp");
    });
    
    it("should test AngularJS service with Angular dependencies", 
      angular.mock.inject((userService: any, legacyDataService: any) => {
        const users = userService.getUsers();
        const processedUsers = legacyDataService.processData(users);
        
        expect(processedUsers).toHaveLength(2);
        expect(processedUsers[0].processed).toBe(true);
      })
    );
  });
});

Testing Best Practices

Isolation Testing:

// Test Angular services without AngularJS dependencies when possible
describe("UserService (Isolated)", () => {
  let service: UserService;
  
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [UserService]
    });
    service = TestBed.inject(UserService);
  });
  
  it("should return users", () => {
    const users = service.getUsers();
    expect(users).toBeDefined();
  });
});

Integration Testing:

// Test hybrid interactions only when necessary
describe("UserService (Integration)", () => {
  let service: UserService;
  
  beforeEach(() => {
    const testingModule = createAngularTestingModule(["legacyModule"]);
    TestBed.configureTestingModule({
      imports: [testingModule],
      providers: [UserService]
    });
    service = TestBed.inject(UserService);
  });
  
  it("should work with legacy services", () => {
    // Test actual hybrid behavior
    const result = service.processWithLegacyService("data");
    expect(result).toBeDefined();
  });
});

Mock and Spy Support

The testing utilities work with standard testing frameworks:

import { TestBed } from "@angular/core/testing";
import { createAngularTestingModule } from "@angular/upgrade/static/testing";

describe("Service with Mocks", () => {
  let service: MyService;
  let mockAngularJSService: jasmine.SpyObj<any>;
  
  beforeEach(() => {
    // Create mock AngularJS service
    mockAngularJSService = jasmine.createSpyObj("mockService", ["getData"]);
    mockAngularJSService.getData.and.returnValue("mock data");
    
    // Override AngularJS module with mock
    angular.module("testModule", [])
      .value("angularJSService", mockAngularJSService);
    
    const testingModule = createAngularTestingModule(["testModule"]);
    TestBed.configureTestingModule({
      imports: [testingModule],
      providers: [MyService]
    });
    
    service = TestBed.inject(MyService);
  });
  
  it("should use mocked AngularJS service", () => {
    const result = service.processData();
    expect(mockAngularJSService.getData).toHaveBeenCalled();
    expect(result).toContain("mock data");
  });
});