Setup and teardown

There are three more acceptance criteria to be implemented. The next in the list is as follows:

"Given an investment, it should have the invested shares' quantity."

Writing it should be as simple as the previous spec was. In the InvestmentSpec.js file inside the spec folder, you can translate this new criterion into a new spec called should have the invested shares' quantity, as follows:

describe("Investment", function() {
  it("should be of a stock", function() {
    var stock = new Stock();
    var investment = new Investment({
      stock: stock,
      shares: 100
    });
    expect(investment.stock).toBe(stock);
  });

  it("should have the invested shares' quantity", function() {
    var stock = new Stock();
    var investment = new Investment({
      stock: stock,
      shares: 100
    });
    expect(investment.shares).toEqual(100);
  });
});

You can see that apart from having written the new spec, we have also changed the call to the Investment constructor to support the new shares parameter.

To do so, we used an object as a single parameter in the constructor to simulate named parameters, a feature JavaScript doesn't have natively.

Implementing this in the Investment function is pretty simple—instead of having multiple parameters on the function declaration, it has only one, which is expected to be an object. Then, the function probes each of its expected parameters from this object, making the proper assignments, as shown here:

function Investment (params) {
  this.stock = params.stock;
};

The code is now refactored. We can run the tests to see that only the new spec fails, as shown here:

Setup and teardown

This shows the failing shares spec

To fix this, change the Investment constructor to make the assignment to the shares property, as follows:

function Investment (params) {
  this.stock = params.stock;
  this.shares = params.shares;
};

Finally, everything on your screen is green:

Setup and teardown

This shows the passing shares spec

But as you can see, the following code, which instantiates Stock and Investment, is duplicated on both specs:

var stock = new Stock();
var investment = new Investment({
  stock: stock,
  shares: 100
});

To eliminate this duplication, Jasmine provides another global function called beforeEach that, as the name states, is executed once before each spec. So, for these two specs, it will run twice—once before each spec.

Refactor the previous specs by extracting the setup code using the beforeEach function:

describe("Investment", function() {
  var stock, investment;

  beforeEach(function() {
    stock = new Stock();
    investment = new Investment({
      stock: stock,
      shares: 100
    });
  });

  it("should be of a stock", function() {
    expect(investment.stock).toBe(stock);
  });

  it("should have the invested shares quantity", function() {
    expect(investment.shares).toEqual(100);
  });
});

This looks much cleaner; we not only removed the code duplication, but also simplified the specs. They became much easier to read and maintain since their only responsibility now is to fulfill the expectation.

There is also a teardown function (afterEach) that sets the code to be executed after each spec. It is very useful in situations where a cleanup is required after each spec. We will see an example of its application in Chapter 6, Light Speed Unit Testing.

To finish the specification of Investment, add the remaining two specs to the InvestmentSpec.js file, inside the spec folder:

describe("Investment", function() {
  var stock;
  var investment;

  beforeEach(function() {
    stock = new Stock();
    investment = new Investment({
      stock: stock,
      shares: 100,
      sharePrice: 20
    });
  });

  //... other specs

  it("should have the share paid price", function() {
    expect(investment.sharePrice).toEqual(20);
  });

  it("should have a cost", function() {
    expect(investment.cost).toEqual(2000);
  });
});

Run the specs to see them fail, as shown in the following screenshot:

Setup and teardown

This shows the failing cost and price specs

Add the following code to fix them in the Investment.js file inside the src folder:

function Investment (params) {
  this.stock = params.stock;
  this.shares = params.shares;
  this.sharePrice = params.sharePrice;
  this.cost = this.shares * this.sharePrice;
};

Run the specs for the last time to see them pass:

Setup and teardown

This shows all four Investment specs passing

Tip

It is important to always see a spec fail before writing the code to fix it; otherwise, how would you know that you really need to fix it? Imagine this as a way to test the test.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset