a_mock Mocking Framework

raw JSON →
2.0.5 verified Sun Apr 19 auth: no javascript

a_mock is a focused JavaScript mocking framework designed to be used with any JavaScript testing framework. It enables the creation of both partial and strict mocks, offering granular control over function behavior for testing purposes. Developers can define specific expectations for arguments (single, multiple, arrays, and complex objects), specify return values, configure exceptions to be thrown, and manage call repetition. The library provides capabilities for ignoring arguments or entire calls when precision isn't necessary. It is currently at version 2.0.5 and includes TypeScript type definitions, facilitating its use in TypeScript projects. While a_mock emphasizes explicit expectation setup and strict argument matching, particularly for object arguments, its core utility lies in providing a clear, declarative API for creating test doubles without imposing a specific test runner or assertion library. The release cadence for a_mock is not explicitly detailed in the provided documentation, but it presents as a stable, utility-focused library for fundamental mocking scenarios.

error throws unexpected arguments
cause A strict mock was called with arguments that do not match any active `expect()` criteria, or all predefined expectations have already been consumed.
fix
Add an expect() clause for the specific arguments being used, configure the expectation with repeatAny(), or use ignore() / ignoreAll() if argument matching is not necessary for that call path.
error throws unexpected arguments cause leaf properties are not equal
cause A mock expectation was set for an object (struct), but the object provided during the mock call did not have exactly matching leaf properties or values as defined in the expectation.
fix
Verify that the object passed to the mock call precisely matches the structure and leaf property values defined in the mock.expect({ ... }) call.
error Error: invalid operation
cause The mock was specifically configured using `mock.expect().throw(errorInstance)` to throw a particular error for the current call.
fix
This is expected behavior as per the mock's configuration. If unintended, review and remove or reconfigure the throw() expectation in your test setup.
gotcha Strict mocks (created without an original function) will throw an 'unexpected arguments' error if called with any arguments that do not precisely match a predefined expectation, or if called after all expectations have been consumed.
fix Ensure all anticipated call paths are covered by `expect()` calls, or utilize `repeatAny()` for indefinitely repeatable expectations. For calls where argument specifics are not critical, consider using `ignore()` or `ignoreAll()`.
gotcha When matching objects (referred to as 'structs' in the documentation), `a_mock` performs strict equality checks exclusively on *leaf properties*. This means an empty object expectation `{}` will not match any non-empty object provided, and all leaf property values in the actual object must exactly match those in the expected struct for a successful match.
fix Design mock expectations with precise leaf property values for object arguments. If exact object matching is not required, consider using argument ignoring functions like `ignore()` or `ignoreAll()`.
gotcha Expectations are consumed sequentially in the order they are defined. Once an `expect()` call is met and it's not configured with `repeatAny()`, that expectation is removed. Subsequent calls made after all expectations have been consumed will result in an 'unexpected arguments' error.
fix Carefully plan the order of your `expect()` calls. For expectations that should be matched multiple times, use `repeat(count)` or `repeatAny()`. For partial mocks, ensure that any unmatched arguments should genuinely fall back to the original function.
npm install a_mock
yarn add a_mock
pnpm add a_mock

Demonstrates creating both strict and partial mocks, showing how to define expected arguments, handle multiple calls, and observe strict matching behavior with unexpected inputs.

import { mock } from 'a_mock';

// Minimal declaration for a_mock to satisfy TypeScript for quickstart
// In a real project, these types would be automatically available from 'a_mock'
declare module 'a_mock' {
    interface MockExpectation {
        return(value: any): MockExpectation;
        throw(error: Error): MockExpectation;
        repeat(count: number): MockExpectation;
        repeatAny(): MockExpectation;
        whenCalled(callback: (...args: any[]) => any): MockExpectation;
    }

    interface MockInstance extends Function {
        expect(...args: any[]): MockExpectation;
        ignore(): MockInstance;
        ignoreAll(): { return(value: any): MockExpectation; };
    }

    function mock(originalFunction?: Function): MockInstance;
}

// Mocking a function that expects multiple arguments
const myMock = mock();

myMock.expect('firstArg1', 'secondArg1').return('fake1');
myMock.expect('firstArg2', 'secondArg2').return('fake2');

console.log('Call 1:', myMock('firstArg1', 'secondArg1')); // Expected: fake1
console.log('Call 2:', myMock('firstArg2', 'secondArg2')); // Expected: fake2

try {
  myMock('foo');
} catch (e: any) {
  console.error("Error on single arg call:", e.message); // Expected: throws unexpected arguments
}

try {
  myMock('foo', 'bar');
} catch (e: any) {
  console.error("Error on unexpected args:", e.message); // Expected: throws unexpected arguments
}

// Demonstrate a partial mock
const originalAdder = (a: number, b: number) => `Original sum: ${a + b}`;
const partialAdderMock = mock(originalAdder);

partialAdderMock.expect(10, 20).return('Mocked 10+20');

console.log('Partial mock call 1:', partialAdderMock(10, 20)); // Expected: Mocked 10+20
console.log('Partial mock call 2:', partialAdderMock(5, 5));   // Expected: Original sum: 10 (falls back)