Classes + Testing
Objective
- ECMAScript modules (ESM).
- Classes, constructors, and inheritance.
- Fields, methods, and encapsulation.
- Static fields and methods.
- Abstract classes and methods?
- JavaScript Object Notation (JSON) for serialization and deserialization.
- Unit testing using Mocha (opens in a new tab) and Chai (opens in a new tab).
1 Modules
Build a simple banking application that manages accounts and provides various operations such as depositing to, withdrawing from, adding, removing, and retrieving accounts.
- 
Initialize your directory as a package using npm init, then set the module format to ESM inpackage.json:{ "type": "module" }.
- 
Create a Bankmodule,bank.js, where you declare an array,accounts, of object literals to store the following accounts:idbalancetype08a45dd424 502.30 Savings a9e2465841 4,100.00 Current 7160dca601 34,420.55 Current 2efde49d9d 61,023.69 Savings 
- 
Implement and export the following functions in the Bankmodule:- 
add(account)adds either aSavingsorCurrentaccount to the array of accounts and returns its identifier.The identifier is generated using the Nano ID (opens in a new tab) ( nanoid(opens in a new tab)) package.
- 
getAll()return all accounts.
- 
get(id)returns an account by identifier.
- 
remove(id)deletes an account by identifier.
- 
deposit(id, amount)adds the amount to the account balance.
- 
withdraw(id, amount)subtracts the amount from the account balance, if it has sufficient balance.
- 
totalBalance()returns the total balance for all accounts.
- 
deductFee(fee)deducts a monthly fee from the balance of allCurrentaccounts.
- 
distributeBenefit(percentage)increases the balance of allSavingsaccounts by a benefit percentage.
- 
toJSON()returns the array of accounts as a JSON string.
- 
fromJSON(json)parses the JSON string and returns an array of accounts.
 
- 
- 
Write an application, app.js, to test theBankmodule by creating a couple ofCurrentandSavingsaccounts, then performing a few deposits and withdrawals:- Charge a monthly fee of 10.
- Display the total balance of all accounts after charging the monthly fee.
- Distribute a 6%benefit.
- Display the total balance of all accounts after distributing the benefit.
- Display the list of accounts in JSON format.
 
- Charge a monthly fee of 
2 Classes
Classes in JavaScript are, for the most part, syntactic sugar for prototype-based inheritance (opens in a new tab).
Rewrite the application from 1 Modules using the classes Bank, BankAccount, CurrentAccount, and SavingsAccount, as specified in the UML diagram, where a Bank is composed of multiple BankAccounts and each BankAccount is either a CurrentAccount or a SavingsAccount.
Complete the 3 Exceptions guide to learn more about throwing and catching exceptions.
3 Unit Testing
Install the Mocha Test Explorer (opens in a new tab) and the ES6 Mocha Snippets (opens in a new tab) extensions for Visual Studio Code.
Mocha (opens in a new tab) is a test framework that supports test-driven development (TDD) by providing a simple interface for writing and running tests. Mocha tests run serially, allowing for flexible and accurate reporting, while mapping uncaught exceptions to the correct test cases.
Chai (opens in a new tab) is an assertion library that can follow a test-driven or behavior-driven
development (BDD), can be
paired with any testing framework, and supports plugins such as
chai-superagent (opens in a new tab) and
sinon-chai (opens in a new tab).
There are numerous testing tools, frameworks, and libraries listed under Links → Testing.
- 
Install the convert(opens in a new tab) package usingnpm install convert, then import and use is to convert a few units:index.jsimport convert from "convert"; console.log("360 s = %d m", convert(360, "seconds").to("minutes")); console.log("5 km = %f mi", convert(5, "kilometers").to("nautical miles")); console.log("12 lb = %d oz", convert(12, "pounds").to("ounces")); console.log("8,192 B = %d KiB", convert(8192, "bytes").to("KiB")); console.log("10 atm = %f kPa", convert(10, "atmospheres").to("kPa")); console.log("451 °F = %f °C", convert(451, "fahrenheit").to("celsius"));
- 
Install Mocha (opens in a new tab) as local development dependency: npm install --save-dev mocha
- 
Create a test/convert.spec.jstest specification file, that usesmochaandassert, to test some of the unit conversions provided byconvert:test/convert.spec.jsimport convert from "convert"; import assert from "assert"; describe("convert", function () { describe("time", function () { it("should convert 60 s to 1 m", function () { assert.equal(convert(60, "seconds").to("minutes"), 1); }); it("should convert 1h to 3,600 s", function () { assert.equal(convert(1, "hours").to("seconds"), 3600); }); }); describe("mass", function () { it("should convert 1 kg to 2.2 lb", function () { assert.equal(convert(1, "kg").to("pounds"), 2.2); }); }); });
- 
Run the tests using npx mochaand fix the failing test case usingNumber.toFixed()(opens in a new tab).
- 
Add a script to package.jsonto run the tests usingnpm test:package.json{ "scripts": { "test": "mocha" } }
- 
Install Chai (opens in a new tab) as a local development dependency: npm install --save-dev chai
- 
Rewrite the test assertions in a BDD-style using chai.expect()(opens in a new tab):test/convert.spec.jsimport convert from "convert"; import { describe, it } from "mocha"; import { expect } from "chai"; describe("convert", function () { describe("time", function () { it("should convert 60 s to 1 m", function () { expect(convert(60, "seconds").to("minutes")).to.be.equal(1); }); it("should convert 1 h to 3600 s", function () { expect(convert(1, "hours").to("seconds")).to.be.equal(3600); }); }); describe("mass", function () { it("should convert 1 kg to 2.2 lb", function () { expect(convert(1, "kg").to("pounds")).to.be.equal(2.2); }); }); describe("best", function () { it("should convert to best with unit and quantity properties", function () { expect(convert(1500, "meters").to("best")).to.have.own.property( "unit", ); expect(convert(1500, "meters").to("best")).to.have.own.property( "quantity", ); }); }); });
- 
Write unit tests, using Mocha + Chai, for each method of the Bankclass and run them.
Resources
- MDN: Using classes (opens in a new tab), Working with objects (opens in a new tab), Keyed collections (opens in a new tab), Inheritance and the prototype chain (opens in a new tab), JavaScript modules (opens in a new tab), Classes (opens in a new tab), new.target(opens in a new tab),constructor(opens in a new tab)
- Comparing the best Node.js unit testing frameworks (opens in a new tab)
- Testing frameworks for Node.js (opens in a new tab)
- Eloquent JavaScript | The Secret Life of Objects (opens in a new tab)
- ES modules: A cartoon deep-dive (opens in a new tab)
- TDD vs BDD vs ATDD: Key Differences (opens in a new tab)