BDD-style assertions that extend Object.prototype with a should property for natural language assertions. The should interface enables expressive test syntax by adding assertion capabilities directly to JavaScript objects.
Activates the should interface by extending Object.prototype with should property getter/setter.
/**
* Activates the should interface by extending Object.prototype
* Must be called once before using should-style assertions
* @returns void
*/
function should(): void;Usage Examples:
import { should } from "chai";
// Activate should interface
should();
// Now all objects have .should property
(42).should.equal(42);
("hello").should.be.a("string");
([1, 2, 3]).should.have.lengthOf(3);
({ name: "Alice" }).should.have.property("name", "Alice");Static methods available on the should object for explicit failure and utility functions.
/**
* Throws an assertion error with optional context
* @param actual - The actual value (optional)
* @param expected - The expected value (optional)
* @param message - Custom error message (optional)
* @param operator - Comparison operator (optional)
* @throws AssertionError
*/
should.fail(actual?: any, expected?: any, message?: string, operator?: string): never;
/**
* Non-strict equality assertion for should interface
* @param actual - Actual value
* @param expected - Expected value
* @param message - Optional error message
*/
should.equal(actual: any, expected: any, message?: string): void;
/**
* Tests that function throws an error
* @param fn - Function to test
* @param errorType - Expected error constructor
* @param errorMessage - Expected error message (string or regex)
* @param message - Optional assertion message
*/
should.Throw(fn: Function, errorType?: Function, errorMessage?: string | RegExp, message?: string): void;
should.throw(fn: Function, errorType?: Function, errorMessage?: string | RegExp, message?: string): void; // Alias
/**
* Tests that value exists (not null or undefined)
* @param value - Value to test
* @param message - Optional error message
*/
should.exist(value: any, message?: string): void;Negated versions of static should methods.
/**
* Non-strict inequality assertion for should interface
* @param actual - Actual value
* @param expected - Expected value
* @param message - Optional error message
*/
should.not.equal(actual: any, expected: any, message?: string): void;
/**
* Tests that function does not throw an error
* @param fn - Function to test
* @param errorType - Error constructor to reject
* @param errorMessage - Error message to reject (string or regex)
* @param message - Optional assertion message
*/
should.not.Throw(fn: Function, errorType?: Function, errorMessage?: string | RegExp, message?: string): void;
should.not.throw(fn: Function, errorType?: Function, errorMessage?: string | RegExp, message?: string): void; // Alias
/**
* Tests that value does not exist (null or undefined)
* @param value - Value to test
* @param message - Optional error message
*/
should.not.exist(value: any, message?: string): void;When should() is called, all JavaScript objects gain a should property that returns an Assertion instance.
interface Object {
should: Assertion;
}should(); // Activate should interface
// Equality
(42).should.equal(42);
("42").should.not.equal(42);
({ a: 1 }).should.eql({ a: 1 });
({ a: 1 }).should.deep.equal({ a: 1 });
// Type checking
("hello").should.be.a("string");
(42).should.be.a("number");
([]).should.be.an("array");
({}).should.be.an("object");
// Truthiness
(true).should.be.true;
(false).should.be.false;
(1).should.be.ok;
("").should.not.be.ok;// Numeric comparisons
(5).should.be.above(3);
(5).should.be.at.least(5);
(3).should.be.below(5);
(3).should.be.at.most(3);
(1.5).should.be.within(1, 2);
(1.5).should.be.closeTo(1.6, 0.2);
// String matching
("hello world").should.match(/world/);
("hello world").should.include("world");
("hello world").should.contain("world");const obj = { name: "Alice", age: 25, active: true };
// Property existence and values
obj.should.have.property("name");
obj.should.have.property("age", 25);
obj.should.have.own.property("name");
obj.should.include({ name: "Alice" });
obj.should.deep.include({ name: "Alice", age: 25 });
// Keys
obj.should.have.keys("name", "age", "active");
obj.should.have.any.keys("name", "email");
obj.should.contain.keys("name", "age");
// Nested properties
const nested = { user: { profile: { name: "Bob" } } };
nested.should.have.nested.property("user.profile.name");
nested.should.have.nested.property("user.profile.name", "Bob");const array = [1, 2, 3, 4, 5];
// Length
array.should.have.lengthOf(5);
array.should.have.length.above(3);
// Members
array.should.include(3);
array.should.include.members([2, 4]);
array.should.have.members([1, 2, 3, 4, 5]);
array.should.have.ordered.members([1, 2, 3, 4, 5]);
// Deep member checking
[{a: 1}, {b: 2}].should.deep.include({a: 1});
[{a: 1}, {b: 2}].should.have.deep.members([{a: 1}, {b: 2}]);
// Empty collections
[].should.be.empty;
"".should.be.empty;
({}).should.be.empty;function throwsError() {
throw new Error("Something went wrong");
}
function returnsValue() {
return 42;
}
// Exception testing with should syntax
throwsError.should.throw();
throwsError.should.throw(Error);
throwsError.should.throw("Something went wrong");
throwsError.should.throw(Error, /went wrong/);
// Static should methods for functions
should.Throw(throwsError);
should.Throw(throwsError, Error);
should.not.Throw(returnsValue);
// Function properties
returnsValue.should.be.a("function");
returnsValue.should.have.property("name", "returnsValue");// Complex chaining with natural language
(42).should.be.a("number").and.be.above(40).and.be.below(50);
// Object validation chains
const user = { name: "Alice", age: 25, email: "alice@example.com" };
user.should.be.an("object")
.that.has.property("name")
.that.is.a("string")
.and.has.length.above(0);
user.should.have.property("email")
.that.matches(/@/);
// Negation chains
("hello").should.not.equal("world");
([1, 2, 3]).should.not.include(4);
user.should.not.have.property("password");// Explicit failures
should.fail("Something went wrong");
should.fail(actual, expected, "Values don't match");
// Existence testing
should.exist(someValue);
should.not.exist(null);
should.not.exist(undefined);
// Equality testing
should.equal(actual, expected);
should.not.equal(actual, different);
// Exception testing
should.Throw(() => { throw new Error(); });
should.not.Throw(() => { return 42; });The should interface modifies Object.prototype, which may conflict with some libraries or environments:
// Safe activation check
if (typeof should === 'function') {
should();
}
// Alternative: use expect or assert interfaces
// These don't modify global prototypes
import { expect, assert } from "chai";Should assertions provide the same detailed error messages as other Chai interfaces:
// This will throw: AssertionError: expected 5 to equal 10
(5).should.equal(10);
// Custom error messages
(5).should.equal(10, "Custom failure message");
// Object diff display
({ a: 1, b: 2 }).should.deep.equal({ a: 1, b: 3 });
// Shows property-by-property diff