or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

browser-mocking.mdhttp-backend.mdindex.mdtesting-utilities.mdtime-control.md
tile.json

testing-utilities.mddocs/

Testing Utilities

Essential testing utilities for module configuration, dependency injection, debugging, browser event simulation, and other testing helpers provided by Angular Mocks.

Capabilities

Module Configuration

Global module function for configuring dependency injection in tests:

/**
 * Configure modules for dependency injection in tests
 * @param {...(string|Function|Object)} modules - Module names, configuration functions, or value objects
 * @returns {Function|*} Configuration function or immediate execution result
 */
module(...modules);

/**
 * Use shared injector across all tests in describe block
 * Enables use of beforeAll/before hooks for shared setup
 */
module.sharedInjector();

Dependency Injection

Global inject function for injecting dependencies into test functions:

/**
 * Inject dependencies into test functions
 * @param {...Function} functions - Functions to inject dependencies into
 * @returns {Function|*} Injection function or immediate execution result
 */
inject(...functions);

/**
 * Enable or disable strict dependency injection
 * @param {boolean} value - Whether to enable strict DI (optional, defaults to true)
 * @returns {Function|*} Configuration function or immediate execution result
 */
inject.strictDi(value?);

Browser Event Simulation

Global function for triggering native browser events on DOM elements:

/**
 * Trigger a native browser event on an element
 * @param {Element|jQuery} element - DOM element or jQuery/jqLite wrapper
 * @param {string} eventType - Event type (optional, auto-detected if not provided)
 * @param {Object} eventData - Additional event data (optional)
 * @returns {void}
 */
browserTrigger(element, eventType?, eventData?);

/**
 * Event data object for configuring triggered events
 */
interface BrowserEventData {
  /** Whether the event bubbles */
  bubbles?: boolean;
  /** Whether the event can be cancelled */
  cancelable?: boolean;
  /** Character code for keyboard events */
  charcode?: number;
  /** Composition data for CompositionEvents */
  data?: string;
  /** Elapsed time for transition/animation events */
  elapsedTime?: number;
  /** Key code for keyboard events */
  keycode?: number;
  /** Modifier keys array (ctrl, alt, shift, meta) */
  keys?: string[];
  /** Related target for mouse events */
  relatedTarget?: Element;
  /** Which key for keyboard events */
  which?: number;
}

Debugging Utilities

Utilities for debugging and inspecting objects in tests:

/**
 * Serialize an object for debugging purposes
 * @param {*} object - Object to serialize and inspect
 * @returns {string} String representation of the object
 */
angular.mock.dump(object);

Component Controller Testing

Service for instantiating component controllers in isolation:

/**
 * Create a component controller for testing
 * @param {string} componentName - Name of the component
 * @param {Object} locals - Local dependencies to inject (optional)
 * @param {Object} bindings - Component bindings (optional)
 * @param {string} ident - Controller identifier (optional)
 * @returns {*} Component controller instance
 */
$componentController(componentName, locals?, bindings?, ident?);

Date Mocking

Mock Date class with timezone support for testing:

/**
 * Mock Date class with timezone offset
 * @param {number} offset - Timezone offset in hours
 * @param {number|string|Date} timestamp - Timestamp to create date from
 * @constructor
 */
function TzDate(offset, timestamp);

// TzDate inherits all Date.prototype methods
interface TzDate extends Date {
  constructor(offset: number, timestamp: number | string | Date);
}

Animation Mocking

Mock animation module for testing animated components:

/**
 * Mock ngAnimate module (angular.mock.animate)
 * Provides mocked animation services with testing utilities
 */
angular.module('ngAnimateMock', ['ng']);

/**
 * Animation mock service with testing methods
 */
interface AnimateMock {
  /**
   * Flush pending animations
   */
  flush(): void;
  
  /**
   * Close and flush all animations, throwing if any are pending
   */
  closeAndFlush(): void;
}

Usage Examples

Module Configuration:

describe('MyService', function() {
  // Load application module
  beforeEach(module('myApp'));
  
  // Load additional modules
  beforeEach(module('ngRoute', 'ngAnimate'));
  
  // Module with inline configuration
  beforeEach(module(function($provide) {
    $provide.value('apiEndpoint', 'http://test-api.com');
  }));
  
  // Module with value object
  beforeEach(module({
    config1: 'value1',
    config2: 'value2'
  }));
  
  it('should use configured values', inject(function(apiEndpoint, config1) {
    expect(apiEndpoint).toBe('http://test-api.com');
    expect(config1).toBe('value1');
  }));
});

Shared Injector:

describe('ExpensiveSetup', function() {
  var MyService, expensiveData;
  
  module.sharedInjector();
  
  beforeAll(module('myApp'));
  
  beforeAll(inject(function(_MyService_) {
    MyService = _MyService_;
    expensiveData = MyService.performExpensiveCalculation();
  }));
  
  it('should have calculated data', function() {
    expect(expensiveData).toBeDefined();
    expect(expensiveData.result).toBe(42);
  });
  
  it('should reuse the same service instance', function() {
    expect(MyService.getCalculatedData()).toBe(expensiveData);
  });
});

Dependency Injection:

describe('Service Integration', function() {
  beforeEach(module('myApp'));
  
  it('should inject multiple services', inject(function($http, $q, MyService) {
    expect($http).toBeDefined();
    expect($q).toBeDefined();
    expect(MyService).toBeDefined();
  }));
  
  // Using underscore wrapping to avoid variable name conflicts
  it('should support underscore wrapping', function() {
    var MyService;
    
    inject(function(_MyService_) {
      MyService = _MyService_;
    });
    
    expect(MyService).toBeDefined();
  });
});

Browser Event Simulation:

describe('Button Click Handler', function() {
  var element, $scope;
  
  beforeEach(module('myApp'));
  beforeEach(inject(function($compile, $rootScope) {
    $scope = $rootScope.$new();
    $scope.clickCount = 0;
    $scope.handleClick = function() {
      $scope.clickCount++;
    };
    
    element = $compile('<button ng-click="handleClick()">Click me</button>')($scope);
    $scope.$digest();
  }));
  
  it('should handle click events', function() {
    browserTrigger(element, 'click');
    
    expect($scope.clickCount).toBe(1);
  });
  
  it('should handle keyboard events', function() {
    browserTrigger(element, 'keydown', {
      keycode: 13, // Enter key
      keys: ['ctrl'] // With Ctrl modifier
    });
    
    // Assert expected behavior
  });
});

Component Controller Testing:

describe('UserProfileComponent', function() {
  var $componentController;
  
  beforeEach(module('myApp'));
  beforeEach(inject(function(_$componentController_) {
    $componentController = _$componentController_;
  }));
  
  it('should initialize component with bindings', function() {
    var bindings = {
      user: {id: 1, name: 'John Doe'},
      onSave: jasmine.createSpy('onSave')
    };
    
    var ctrl = $componentController('userProfile', null, bindings);
    
    expect(ctrl.user).toBe(bindings.user);
    expect(ctrl.onSave).toBe(bindings.onSave);
    
    // Test component methods
    ctrl.save();
    expect(bindings.onSave).toHaveBeenCalled();
  });
});

Object Debugging:

describe('Complex Data Processing', function() {
  it('should process complex objects', inject(function(DataProcessor) {
    var complexObject = {
      nested: {
        array: [1, 2, {deep: 'value'}],
        fn: function() { return 'test'; }
      }
    };
    
    var result = DataProcessor.process(complexObject);
    
    // Use dump for debugging complex objects
    console.log('Input:', angular.mock.dump(complexObject));
    console.log('Result:', angular.mock.dump(result));
    
    expect(result).toBeDefined();
  }));
});

Date Mocking:

describe('Timezone-dependent Service', function() {
  it('should handle different timezones', function() {
    // Create dates in different timezones
    var utcDate = new angular.mock.TzDate(0, '2023-01-01T12:00:00Z');
    var estDate = new angular.mock.TzDate(-5, '2023-01-01T12:00:00Z');
    
    expect(utcDate.getHours()).toBe(12);
    expect(estDate.getHours()).toBe(7); // 5 hours behind UTC
  });
});

Animation Testing:

describe('Animated Component', function() {
  var $animate;
  
  beforeEach(module('myApp', 'ngAnimateMock'));
  beforeEach(inject(function(_$animate_) {
    $animate = _$animate_;
  }));
  
  it('should handle animations', function() {
    var element = angular.element('<div class="animated"></div>');
    
    $animate.addClass(element, 'fade-in');
    
    // Flush pending animations
    $animate.flush();
    
    expect(element.hasClass('fade-in')).toBe(true);
  });
});

Types

// Module Configuration Types
type ModuleConfig = string | Function | Object;

// Injection Function Type
type InjectionFunction = (...args: any[]) => void;

// Component Controller Locals
interface ComponentLocals {
  [key: string]: any;
}

// Component Bindings
interface ComponentBindings {
  [key: string]: any;
}

// Browser Event Configuration
interface BrowserEventConfig {
  bubbles?: boolean;
  cancelable?: boolean;
  charcode?: number;
  data?: string;
  elapsedTime?: number;
  keycode?: number;
  keys?: string[];
  relatedTarget?: Element;
  which?: number;
}