Testing utilities provide helper functions for unit testing hybrid applications with mixed Angular and AngularJS dependencies, enabling comprehensive test coverage during migration.
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();
});
});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"]);
});
});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);
})
);
});
});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();
});
});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");
});
});