Expressive, readable, framework-agnostic BDD-style assertion library for JavaScript testing.
—
Methods for testing the type and class of values using JavaScript's built-in type system and constructor checking.
Test the result of typeof operation.
/**
* Assert that typeof returns the specified type string
* @param typeName - Expected type name ('string', 'number', 'boolean', etc.)
* @param description - Optional error message
* @returns This assertion for chaining
*/
type(typeName: string, description?: string): Assertion;Usage:
import should from 'should';
'hello'.should.have.type('string');
(42).should.have.type('number');
true.should.have.type('boolean');
undefined.should.have.type('undefined');
({}).should.have.type('object');
(() => {}).should.have.type('function');
// With description
const value = 'test';
value.should.have.type('string', 'Value should be a string');Test if a value is an instance of a constructor function.
/**
* Assert that the value is an instance of the given constructor
* @param constructor - Constructor function to test against
* @param description - Optional error message
* @returns This assertion for chaining
*/
instanceof(constructor: Function, description?: string): Assertion;
instanceOf(constructor: Function, description?: string): Assertion;Usage:
const date = new Date();
date.should.be.instanceof(Date);
date.should.be.instanceOf(Date);
const array = [1, 2, 3];
array.should.be.instanceof(Array);
const error = new Error('test');
error.should.be.instanceof(Error);
class CustomClass {}
const instance = new CustomClass();
instance.should.be.instanceof(CustomClass);
// With description
const regex = /test/;
regex.should.be.instanceof(RegExp, 'Should be a regular expression');Test that a value is a number.
/**
* Assert that the value is of type 'number'
* @returns This assertion for chaining
*/
Number(): Assertion;Usage:
(42).should.be.a.Number();
(3.14).should.be.a.Number();
(-100).should.be.a.Number();
NaN.should.be.a.Number(); // NaN is still type 'number'
Infinity.should.be.a.Number();
// Chaining with other number assertions
(42).should.be.a.Number().and.be.above(0);Test that a value is a string.
/**
* Assert that the value is of type 'string'
* @returns This assertion for chaining
*/
String(): Assertion;Usage:
'hello'.should.be.a.String();
''.should.be.a.String();
`template`.should.be.a.String();
const message = 'test';
message.should.be.a.String().and.have.length(4);Test that a value is a boolean.
/**
* Assert that the value is of type 'boolean'
* @returns This assertion for chaining
*/
Boolean(): Assertion;Usage:
true.should.be.a.Boolean();
false.should.be.a.Boolean();
const isValid = true;
isValid.should.be.a.Boolean().and.be.true();Test that a value is an array.
/**
* Assert that the value is an Array instance
* @returns This assertion for chaining
*/
Array(): Assertion;Usage:
[1, 2, 3].should.be.an.Array();
[].should.be.an.Array();
const items = ['a', 'b', 'c'];
items.should.be.an.Array().and.have.length(3);
// Arrays are also Objects in JavaScript
const arr = [1, 2, 3];
arr.should.be.an.Array().and.be.an.Object();Test that a value is an object.
/**
* Assert that the value is of type 'object' (includes arrays, dates, etc.)
* @returns This assertion for chaining
*/
Object(): Assertion;Usage:
({}).should.be.an.Object();
({ name: 'john' }).should.be.an.Object();
// Arrays, dates, and other objects are also Objects
[1, 2, 3].should.be.an.Object();
new Date().should.be.an.Object();
/regex/.should.be.an.Object();
const user = { name: 'john' };
user.should.be.an.Object().and.have.property('name');Test that a value is a function.
/**
* Assert that the value is of type 'function'
* @returns This assertion for chaining
*/
Function(): Assertion;Usage:
(() => {}).should.be.a.Function();
function named() {}
named.should.be.a.Function();
class MyClass {}
MyClass.should.be.a.Function(); // Classes are functions
const callback = (x) => x * 2;
callback.should.be.a.Function();Test that a value is a Date instance.
/**
* Assert that the value is a Date instance
* @returns This assertion for chaining
*/
Date(): Assertion;Usage:
new Date().should.be.a.Date();
new Date('2023-01-01').should.be.a.Date();
const timestamp = new Date();
timestamp.should.be.a.Date().and.be.instanceof(Date);Test that a value is an Error instance.
/**
* Assert that the value is an Error instance
* @returns This assertion for chaining
*/
Error(): Assertion;Usage:
new Error().should.be.an.Error();
new TypeError().should.be.an.Error();
new RangeError().should.be.an.Error();
try {
throw new Error('test error');
} catch (err) {
err.should.be.an.Error().and.have.property('message', 'test error');
}Test that a value is null.
/**
* Assert that the value is null
* @returns This assertion for chaining
*/
null(): Assertion;
Null(): Assertion;Usage:
// Must use functional syntax since null has no properties
const should = require('should/as-function');
should(null).be.null();
should(null).be.Null();
let value = null;
should(value).be.null();Test that a value is undefined.
/**
* Assert that the value is undefined
* @returns This assertion for chaining
*/
undefined(): Assertion;
Undefined(): Assertion;Usage:
const should = require('should/as-function');
should(undefined).be.undefined();
should(undefined).be.Undefined();
let uninitialized;
should(uninitialized).be.undefined();
const obj = {};
should(obj.nonexistent).be.undefined();Test that a value is an arguments object.
/**
* Assert that the value is an arguments object
* @returns This assertion for chaining
*/
arguments(): Assertion;
Arguments(): Assertion;Usage:
function testFunction() {
arguments.should.be.arguments();
arguments.should.be.Arguments();
}
testFunction(1, 2, 3);
// Arguments objects are array-like but not arrays
function compare() {
arguments.should.be.arguments();
arguments.should.not.be.an.Array();
}Test that a value has a specific class name via Object.prototype.toString.
/**
* Assert that the value has the specified class name
* @param className - Expected class name from Object.prototype.toString
* @returns This assertion for chaining
*/
class(className: string): Assertion;
Class(className: string): Assertion;Usage:
[].should.have.class('Array');
{}.should.have.class('Object');
new Date().should.have.class('Date');
/regex/.should.have.class('RegExp');
'string'.should.have.class('String');
(42).should.have.class('Number');
// Custom class names
class CustomClass {}
const instance = new CustomClass();
instance.should.have.class('Object'); // Custom classes show as 'Object'Test that a value is iterable (has Symbol.iterator).
/**
* Assert that the value is iterable (implements Symbol.iterator)
* @returns This assertion for chaining
*/
iterable(): Assertion;Usage:
[1, 2, 3].should.be.iterable();
'hello'.should.be.iterable();
new Set([1, 2, 3]).should.be.iterable();
new Map().should.be.iterable();
// Objects are not iterable by default
({}).should.not.be.iterable();Test that a value is an iterator (has next method).
/**
* Assert that the value is an iterator (has next method)
* @returns This assertion for chaining
*/
iterator(): Assertion;Usage:
const arr = [1, 2, 3];
const iter = arr[Symbol.iterator]();
iter.should.be.iterator();
const set = new Set([1, 2, 3]);
const setIter = set.values();
setIter.should.be.iterator();Test that a value is a generator object.
/**
* Assert that the value is a generator object
* @returns This assertion for chaining
*/
generator(): Assertion;Usage:
function* generatorFunc() {
yield 1;
yield 2;
}
const gen = generatorFunc();
gen.should.be.generator();
// Generator functions themselves are not generators
generatorFunc.should.not.be.generator();
generatorFunc.should.be.a.Function();All type assertions can be negated and chained:
const value = 'hello';
value.should.not.be.a.Number();
value.should.be.a.String().and.not.be.empty();
const obj = { count: 5 };
obj.should.be.an.Object().and.not.be.an.Array();
obj.count.should.be.a.Number().and.not.be.a.String();Install with Tessl CLI
npx tessl i tessl/npm-should