dimanche 26 juin 2016

Basic but proper use of beforeEach() or afterEach() with mocha.js and chai.js

I want to use mocha/chai to test code related to binary search trees. Here, I am testing the public insert method. I want to use beforeEach() and/or afterEach() hooks to reset the test environment prior to each it() statement so that I don't have to completely repeat the basics. However, I keep getting various errors.

Spec

describe("BinarySearchTree insert function", function() {

  beforeEach(function() {
    var binarySearchTree = new BinarySearchTree();
    binarySearchTree.insert(5);
  });

  it("creates a root node with value equal to the first inserted value", function () {
    expect(binarySearchTree.root.value).to.equal(5);
  });

  it("has a size equal to the amount of inserted values", function () {
    binarySearchTree.insert(3);
    expect(binarySearchTree.size).to.equal(2);
  });

  it("returns an error for non-unique values", function () {
    binarySearchTree.insert(3);
    expect(binarySearchTree.insert(3)).to.throw(String);
  });

  it("if inserted value is larger than current node, make or descend to rightChild", function () {
    binarySearchTree.insert(3);
    binarySearchTree.insert(10);
    binarySearchTree.insert(7);
    expect(binarySearchTree.root.rightChild.value).to.equal(10);
  });

});

Error: ReferenceError: binarySearchTree is not defined

In truth, I expected errors before there is no afterEach() resetting the test environment, not because binarySearchTree is not defined. I'd like to accomplish this, if at all possible, with only Mocha and Chai (and not other packages like Sinon, etc).

Tested Code

exports.Node = Node;

function Node(value) {
  this.value = value;
  this.leftChild = null;
  this.rightChild = null;
}

exports.BinarySearchTree = BinarySearchTree;

function BinarySearchTree() {
  this.root = null;
  this.size = 0;
}

BinarySearchTree.prototype.insert = function(value) {
  // 1) when root node is already instantiated
  if (this.root === null) {
    // tree is empty
    this.root = new Node(value);
    this.size++;
  } else {
  // 2) nodes are already inserted
    var findAndInsert = function (currentNode) {
      if (value === currentNode.value) {
        throw new Error('must be a unique value');
      }
      // base case
      if (value > currentNode.value) {
        // belongs in rightChild
        if (currentNode.rightChild === null) {
          currentNode.rightChild = new Node(value);
        } else {
          findAndInsert(currentNode.rightChild);
        }
      } else if (value < currentNode.value) {
        // belongs in leftChild
        if (currentNode.leftChild === null) {
          currentNode.leftChild = new Node(value);
        } else {
          findAndInsert(currentNode.leftChild);
        }
      }
    };
    findAndInsert(this.root);
    this.size++;
  }
};

Bonus question... I'm not sure if I am properly testing for the thrown error (when a non-unique value is inserted)?

Aucun commentaire:

Enregistrer un commentaire