Installation Mocha is a test framework for NodeJS. Chai is assertion library for any test framework. npm i mocha chai --save-dev Add script into package.json "scripts": { "dev": "node exportAllPostsCreate && next dev", "build": "node exportAllPostsCreate && next build", "start": "next start", "lint": "next lint", "test": "jest --watch || true", "mocha": "mocha" } By default mocha looks for a test folder, where we can create test files. // test/mytest.js const assert = require('chai').assert describe('basic tests', () => { it('should return 5', () => { assert.equal(2 + 3, 5) }) }) Run tests with command npm run mocha and see the output. basic tests ✔ should return 5 1 passing (2ms) Assert vs Expect const assert = require('chai').assert const expect = require('chai').expect describe('assert', () => { it('should return 5', () => { assert.equal(2 + 3, 5) expect(2 + 3).to.equal(5) }) it('should be a string', () => { assert.typeOf('hi', 'string') expect('hi').to.be.a('string') }) it('should be > 5', () => { assert.isAbove(100, 99) expect(100).to.be.above(99) }) }) Cosmetic properties They do not mean anything: .to , .be , .been , .is , .that , .which , .and , .has , .have , .with , .at , .of , .same , .but , .does , .still , .also describe('cosmetic props', () => { it('should return 5', () => { expect(2 + 3).equal(5) expect(2 + 3).to.equal(5) expect(2 + 3).to.be.equal(5) }) }) Assertions Expect & should Expect & should assertion methods . not , deep , nested , own , ordered , any , all , a(type) , include(val) , ok , true , false , null , undefined , NaN , exist , empty , arguments , equal(val) , eql(obj) , above(n) , least(n) , below(n) , most(n) , within(start, finish) , instanceof(constructor) , property(name) , ownPropertyDescriptor(name) , lengthOf(n) , match(re) , string(str) , keys(key1, key2) , throw() , respondTo(method) , itself , satisfy(matcher) , closeTo(expected, delta) , members(set) , oneOf(list) , change(subject) , increase(subject) , decrease(subject) , by(delta) , extensible , sealed , frozen , finite , fail() Assert Assert methods . fail , isOk , isNotOk , equal , notEqual , strictEqual , notStrictEqual , deepEqual , notDeepEqual , isAbove , isAtLeast , isBelow , isAtMost , isTrue , isNotTrue , isFalse , isNotFalse , isNull , isNotNull , isNaN , isNotNaN , exists , notExists , isUndefined , isDefined , isFunction , isNotFunction , isObject , isNotObject , isArray , isNotArray , isString , isNotString , isNumber , isNotNumber , isFinite , isBoolean , isNotBoolean , typeOf , notTypeOf , instanceOf , notInstanceOf , include , notInclude , deepInclude , notDeepInclude , nestedInclude , notNestedInclude , deepNestedInclude , notDeepNestedInclude , ownInclude , notOwnInclude , deepOwnInclude , notDeepOwnInclude , match , notMatch , property , notProperty , propertyVal , notPropertyVal , deepPropertyVal , notDeepPropertyVal , nestedProperty , notNestedProperty , nestedPropertyVal , notNestedPropertyVal , deepNestedPropertyVal , notDeepNestedPropertyVal , lengthOf , hasAnyKeys , hasAllKeys , containsAllKeys , doesNotHaveAnyKeys , doesNotHaveAllKeys , hasAnyDeepKeys , hasAllDeepKeys , containsAllDeepKeys , doesNotHaveAnyDeepKeys , doesNotHaveAllDeepKeys , throws , doesNotThrow , operator , closeTo , approximately , sameMembers , notSameMembers , sameDeepMembers , notSameDeepMembers , sameOrderedMembers , notSameOrderedMembers , sameDeepOrderedMembers , notSameDeepOrderedMembers , includeMembers , notIncludeMembers , includeDeepMembers , notIncludeDeepMembers , includeOrderedMembers , notIncludeOrderedMembers , includeDeepOrderedMembers , notIncludeDeepOrderedMembers , oneOf , changes , changesBy , doesNotChange , changesButNotBy , increases , increasesBy , doesNotIncrease , increasesButNotBy , decreases , decreasesBy , doesNotDecrease , doesNotDecreaseBy , decreasesButNotBy , ifError , isExtensible , isNotExtensible , isSealed , isNotSealed , isFrozen , isNotFrozen , isEmpty , isNotEmpty equal it('should return 5', () => { assert.equal(2 + 3, 5) }) typeOf it('should be a string', () => { assert.typeOf('hi', 'string') }) isAbove it('should be > 5', () => { assert.isAbove(100, 5) }) not it('.not', () => { expect(function () { }).to.not.throw() expect({ a: 1 }).to.not.have.property('b') expect([1, 2]).to.be.an('array').that.does.not.include(3) }) deep it('.deep', () => { // Target object deeply (but not strictly) equals `{a: 1}` expect({ a: 1 }).to.deep.equal({ a: 1 }) expect({ a: 1 }).to.not.equal({ a: 1 }) }) ordered it('.ordered', () => { expect([1, 2]).to.have.ordered.members([1, 2]) .but.not.have.ordered.members([2, 1]) }) any it('.any', () => { expect({ a: 1, b: 2 }).to.not.have.any.keys('c', 'd') }) all it('.all', () => { expect({ a: 1, b: 2 }).to.have.all.keys('a', 'b') }) a(type) it('.a(type)', () => { expect('foo').to.be.a('string') expect({ a: 1 }).to.be.an('object') expect(null).to.be.a('null') expect(undefined).to.be.an('undefined') expect(new Error()).to.be.an('error') expect(Promise.resolve()).to.be.a('promise') expect(new Float32Array()).to.be.a('float32array') expect(Symbol()).to.be.a('symbol') expect([1, 2, 3]).to.be.an('array').that.includes(2) expect([]).to.be.an('array').that.is.empty expect('foo').to.be.a('string') }) include it('.include(val)', () => { expect('foobar').to.include('foo') expect([1, 2, 3]).to.include(2) expect({ a: 1, b: 2, c: 3 }).to.include({ a: 1, b: 2 }) expect(new Set([1, 2])).to.include(2) expect(new Map([['a', 1], ['b', 2]])).to.include(2) expect([1, 2, 3]).to.be.an('array').that.includes(2) }) true it('.true', () => { expect(true).to.be.true expect(false).to.not.be.true }) false it('.false', () => { expect(false).to.be.false expect(true).to.not.be.false }) null it('.null', () => { expect(null).to.be.null }) undefined it('.undefined', () => { expect(undefined).to.be.undefined }) NaN it('.NaN', () => { expect(NaN).to.be.NaN expect('foo').to.not.be.NaN }) exist it('.exist', () => { expect(1).to.exist }) empty it('.empty', () => { expect([]).to.be.empty expect('').to.be.empty expect(new Set()).to.be.empty expect(new Map()).to.be.empty expect({}).to.be.empty expect([]).to.be.an('array').that.is.empty expect([1, 2, 3]).to.not.be.empty }) equal it('.equal(val)', () => { expect(1).to.equal(1) expect('foo').to.equal('foo') expect({ a: 1 }).to.deep.equal({ a: 1 }) expect({ a: 1 }).to.not.equal({ a: 1 }) expect([1, 2]).to.deep.equal([1, 2]) expect([1, 2]).to.not.equal([1, 2]) }) above it('.above(n)', () => { expect(2).to.be.above(1) }) least it('.least(n)', () => { expect(2).to.be.at.least(1) expect(2).to.be.at.least(2) expect('foo').to.have.lengthOf.at.least(2) expect(1).to.not.be.at.least(2) }) below it('.below(n', () => { expect(1).to.be.below(2) expect('foo').to.have.lengthOf.below(4) expect([1, 2, 3]).to.have.lengthOf.below(4) }) most it('.most(n)', () => { expect(1).to.be.at.most(2) expect(1).to.be.at.most(1) expect('foo').to.have.lengthOf.at.most(4) expect([1, 2, 3]).to.have.lengthOf.at.most(4) }) within it('.within(start, finish)', () => { expect(2).to.be.within(1, 3) expect([1, 2, 3]).to.have.lengthOf.within(2, 4) }) instanceof it('.instanceof(constructor)', () => { function Cat() { } expect(new Cat()).to.be.an.instanceof(Cat) expect([1, 2]).to.be.an.instanceof(Array) expect({ a: 1 }).to.not.be.an.instanceof(Array) }) property it('.property(name[, val])', () => { expect({ a: 1 }).to.have.property('a') expect({ a: 1 }).to.have.property('a', 1) expect({ x: { a: 1 } }).to.have.deep.property('x', { a: 1 }) expect({ x: { a: 1 } }).to.not.have.property('x', { a: 1 }) expect({ x: { a: 1 } }).to.have.deep.own.property('x', { a: 1 }) expect({ a: { b: ['x', 'y'] } }).to.have.nested.property('a.b[1]') expect({ a: { b: ['x', 'y'] } }).to.have.nested.property('a.b[1]', 'y') }) lengthOf it('.lengthOf(n)', () => { expect([1, 2, 3]).to.have.lengthOf(3) expect('foo').to.have.lengthOf(3) expect(new Set([1, 2, 3])).to.have.lengthOf(3) expect(new Map([['a', 1], ['b', 2], ['c', 3]])).to.have.lengthOf(3) expect([1, 2, 3]).to.have.lengthOf.above(2) expect([1, 2, 3]).to.have.lengthOf.below(4) expect([1, 2, 3]).to.have.lengthOf.at.least(3) expect([1, 2, 3]).to.have.lengthOf.at.most(3) expect([1, 2, 3]).to.have.lengthOf.within(2, 4) }) match it('.match(re)', () => { expect('foobar').to.match(/^foo/) expect('foobar').to.not.match(/taco/) }) string it('.string(str)', () => { expect('foobar').to.have.string('bar') expect('foobar').to.not.have.string('taco') }) keys it('.keys(key1[, key2[, …]])', () => { expect({ a: 1, b: 2 }).to.have.all.keys('a', 'b') expect(['x', 'y']).to.have.all.keys(0, 1) expect({ a: 1, b: 2 }).to.have.all.keys(['a', 'b']) expect(['x', 'y']).to.have.all.keys([0, 1]) expect({ a: 1, b: 2 }).to.have.all.keys({ a: 4, b: 5 }) // ignore 4 and 5 expect(['x', 'y']).to.have.all.keys({ 0: 4, 1: 5 }) // ignore 4 and 5 expect(new Map([['a', 1], ['b', 2]])).to.have.all.keys('a', 'b') expect(new Set(['a', 'b'])).to.have.all.keys('a', 'b') expect({ a: 1, b: 2 }).to.be.an('object').that.has.all.keys('a', 'b') expect(new Set([{ a: 1 }])).to.have.all.deep.keys([{ a: 1 }]) expect(new Set([{ a: 1 }])).to.not.have.all.keys([{ a: 1 }]) expect({ a: 1, b: 2 }).to.not.have.any.keys('c', 'd') expect({ a: 1, b: 2 }).to.have.all.keys('a', 'b') }) respondTo it('.respondTo(method)', () => { function Cat() { } Cat.prototype.meow = function () { } expect(new Cat()).to.respondTo('meow') expect(Cat).to.respondTo('meow') Cat.hiss = function () { } expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow') expect(new Cat()).to.be.an('object').that.respondsTo('meow') }) itself it('.itself', () => { function Cat() { } Cat.prototype.meow = function () { } Cat.hiss = function () { } expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow') }) satisfy it('.satisfy(matcher)', () => { expect(1).to.satisfy(function (num) { return num > 0 }) expect(1).to.not.satisfy(function (num) { return num > 2 }) }) closeTo it('.closeTo(expected, delta)', () => { expect(1.5).to.be.closeTo(1, 0.5) expect(1.5).to.be.closeTo(2, 0.5) expect(1.5).to.be.closeTo(1, 1) }) members it('.members(set)', () => { expect([1, 2, 3]).to.have.members([2, 1, 3]) expect([1, 2, 2]).to.have.members([2, 1, 2]) expect([{ a: 1 }]).to.have.deep.members([{ a: 1 }]) expect([{ a: 1 }]).to.not.have.members([{ a: 1 }]) expect([1, 2, 3]).to.include.members([1, 2]) expect([1, 2, 3]).to.not.have.members([1, 2]) expect([1, 2, 3]).to.include.members([1, 2, 2, 2]) }) oneOf it('.oneOf(list)', () => { expect(1).to.be.oneOf([1, 2, 3]) expect(1).to.not.be.oneOf([2, 3, 4]) expect('Today is sunny').to.contain.oneOf(['sunny', 'cloudy']) expect('Today is rainy').to.not.contain.oneOf(['sunny', 'cloudy']) expect([1, 2, 3]).to.contain.oneOf([3, 4, 5]) expect([1, 2, 3]).to.not.contain.oneOf([4, 5, 6]) }) change it('.change(subject[, prop])', () => { let dots = '' const addDot = () => { dots += '.' } const getDots = () => dots expect(addDot).to.change(getDots) }) decrease it('.decrease(subject[, prop])', () => { let val = 1 const subtractTwo = () => { val -= 2 } const getVal = () => val expect(subtractTwo).to.decrease(getVal) // Not recommended }) by it('.by(delta)', () => { const myObj = { val: 1 } const addTwo = () => { myObj.val += 2 } expect(addTwo).to.increase(myObj, 'val').by(2) }) extensible it('.extensible', () => { expect({ a: 1 }).to.be.extensible const nonExtensibleObject = Object.preventExtensions({}) const sealedObject = Object.seal({}) const frozenObject = Object.freeze({}) expect(nonExtensibleObject).to.not.be.extensible expect(sealedObject).to.not.be.extensible expect(frozenObject).to.not.be.extensible expect(1).to.not.be.extensible }) sealed it('.sealed', () => { const sealedObject = Object.seal({}) const frozenObject = Object.freeze({}) expect(sealedObject).to.be.sealed expect(frozenObject).to.be.sealed expect(1).to.be.sealed }) frozen it('.frozen', () => { const frozenObject = Object.freeze({}) expect(frozenObject).to.be.frozen expect(1).to.be.frozen }) finite it('.finite', () => { expect(1).to.be.finite }) fail it('.fail', () => { expect.fail() expect.fail('custom error message') })