Chai Assertions for Promises
chai-promised extends Chai with assertions about promises. It’s a modern TypeScript fork of the original Chai as Promised library, specifically designed to support Chai >= 5.x with full TypeScript type definitions.
For comprehensive API documentation, see the chai-as-promised documentation.
Installation
If migrating from the original chai-as-promised:
npm uninstall @types/chai-as-promised chai-as-promised --save-dev --force
npm install chai-promised --save-dev
Or using pnpm (recommended):
pnpm remove @types/chai-as-promised chai-as-promised
pnpm add -D chai-promised
Requirements
- Node.js >= 20.10.0
- Chai >= 5.x
Usage
Setup
import { chaiAsPromised } from 'chai-promised';
import * as chai from 'chai';
chai.use(chaiAsPromised);
BDD Style
// Promise fulfillment
expect(Promise.resolve('foo')).to.eventually.equal('foo');
expect(Promise.resolve({ foo: 'bar' })).to.eventually.have.property('foo');
// Promise rejection
expect(Promise.reject(new Error('boom'))).to.be.rejected;
expect(Promise.reject(new Error('boom'))).to.be.rejectedWith(Error);
expect(Promise.reject(new Error('boom'))).to.be.rejectedWith('boom');
expect(Promise.reject(new Error('boom'))).to.be.rejectedWith(Error, /boom/);
// Shorthand for deep equality
expect(Promise.resolve({ foo: 'bar' })).to.become({ foo: 'bar' });
// Notify for Mocha done() integration
return expect(Promise.resolve('foo')).to.eventually.equal('foo').notify(done);
Assert Style
// Promise-specific assertions
assert.isFulfilled(Promise.resolve('foo'));
assert.isRejected(Promise.reject(new Error('boom')));
assert.isRejected(Promise.reject(new Error('boom')), Error);
assert.isRejected(Promise.reject(new Error('boom')), /boom/);
// assert.eventually for standard assertions
assert.eventually.equal(Promise.resolve('foo'), 'foo');
assert.eventually.property(Promise.resolve({ foo: 'bar' }), 'foo');
assert.eventually.lengthOf(Promise.resolve([1, 2, 3]), 3);
// Shorthand methods
assert.becomes(Promise.resolve({ foo: 'bar' }), { foo: 'bar' });
assert.doesNotBecome(Promise.resolve(5), 10);
Chaining
All Chai assertions work with .eventually:
expect(Promise.resolve([1, 2, 3]))
.to.eventually.have.length(3)
.and.include(2)
.and.not.include(4);
expect(Promise.resolve({ foo: 'bar', baz: 'qux' }))
.to.eventually.have.all.keys('foo', 'baz')
.and.have.property('foo')
.that.is.a('string');
API Overview
Promise-Specific Assertions
.fulfilled- Assert promise is fulfilled.rejected- Assert promise is rejected.rejectedWith(error, [message])- Assert promise is rejected with specific error/message.eventually- Wait for promise and run assertion on resolved value.become(value)- Shorthand for.eventually.deep.equal(value).notify(done)- Mocha integration for async testing
Assert API
assert.isFulfilled(promise, [message])assert.isRejected(promise, [error], [message])assert.becomes(promise, value, [message])assert.doesNotBecome(promise, value, [message])assert.eventually.*- All standard assert methods with promise support
Development
Prerequisites
This project uses pnpm as its package manager:
npm install -g pnpm
pnpm install
Commands
# Run tests
pnpm test
# Build the library
pnpm build
# Lint code
pnpm lint
pnpm lint:fix
# Clean generated files
pnpm clean
TypeScript Support
This library includes comprehensive TypeScript definitions. No @types package is needed.
import { chaiAsPromised, chaiPromised } from 'chai-promised';
// Both exports are available (aliases)
chai.use(chaiAsPromised);
chai.use(chaiPromised);
// Default export is also available
import chaiPromised from 'chai-promised';
chai.use(chaiPromised);
Advanced Configuration
Customizing Promise Transfer
You can customize how promiseness is transferred to assertions using setTransferPromiseness:
import { setTransferPromiseness } from 'chai-promised';
setTransferPromiseness((assertion, promise) => {
assertion.then = promise.then.bind(promise);
// Add custom promise methods, e.g., for Q or Bluebird
assertion.finally = promise.finally?.bind(promise);
});
// Reset to default behavior
setTransferPromiseness(null);
Transforming Asserter Arguments
You can transform arguments before assertions are evaluated using setTransformAsserterArgs. This is useful for comparing promises against other promises:
import { setTransformAsserterArgs } from 'chai-promised';
// Enable promise comparison by resolving all arguments
setTransformAsserterArgs(Promise.all.bind(Promise));
// Now you can compare promises directly
await expect(Promise.resolve('foo')).to.eventually.equal(Promise.resolve('foo'));
// Reset to default behavior
setTransformAsserterArgs(null);
Compatibility
This library is fully compatible with the original chai-as-promised API (v7.1.2) and maintains the same behavior while providing full TypeScript support for Chai 5.x and 6.x.
License
WTFPL
Contributors
- Domenic Denicola (original chai-as-promised author)
- Rustam Gaifiev