javascriptwebpackjestjsbabel-jest

export/import class to test its methods and constructor


I am stuck on knowing how to test a class.

ship.js

class Ship {
    /**
     * Constructor for setting up a ship object
     * @param {Number} length length of the ship
     * @param {Number} hits how many times the ship has been hit
     * @param {Boolean} isSunk If the ship is sunk
     */
    constructor(length, hits = 0, isSunk = false) {
        this.length = length;
        this.hits = hits;
        this.isSunk = isSunk;
    }

    /**
     * When a ship is hit by a player, or computer, increase it's hit count.
     */
    hit() {
        this.hits += 1;
    }

    /**
     * If the length of the ship is equal to the number of hits, the ship is sunk.
     */
    checkHitsToSink() {
        this.length === this.hits ? (this.isSunk = true) : null;
    }
}

/**
 * Exporting for unit testing
 */
module.exports = Ship;

tests/ship.test.js

const Ship = require('../ship');

test('ship should be {length: 3, hits: 2, isSunk: false}', () => {
    const ship = new Ship(3, 2, false);
    require(ship).toHaveProperty('length', 3);
});

This outputs TypeError: moduleName.startsWith is not a function when I try running this test:

PS C:\Users\brand\Desktop\github\Battleship> npm test

> webpack-template@1.0.0 test
> jest

 FAIL  src/tests/ship.test.js
  × ship should be {length: 3, hits: 2, sunk: false} (2 ms)

  ● ship should be {length: 3, hits: 2, sunk: false}

    TypeError: moduleName.startsWith is not a function

      3 | test('ship should be {length: 3, hits: 2, sunk: false}', () => {
      4 |       const ship = new Ship(3, 2, false);
    > 5 |       require(ship).toHaveProperty(length, 3);
        |       ^
      6 | });
      7 |

      at Resolver.isCoreModule (node_modules/jest-resolve/build/resolver.js:452:20)
      at Object.require (src/tests/ship.test.js:5:2)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        0.707 s, estimated 1 s
Ran all test suites.

Is there a way to test a class doing it like this, or is there a different way completely on testing classes?

I have tried multiple ways to test this class (such as using ESM import/export statements, trying to pass the constructor or the class's methods directly into module.exports, and a few others), but I am coming up with TypeErrors, ReferenceErrors and SyntaxErrors.


Solution

  • there is a correct version:

    const Ship = require('../ship');
    
    test('ship should be {length: 3, hits: 2, isSunk: false}', () => {
        const ship = new Ship(3, 2, false);
        expect(ship).toHaveProperty('length', 3);
    });
    

    the error was caused you use require instead of expect inside test body.