Jasmine basics and thinking in BDD

Based on the application presented previously, we can start writing acceptance criteria that define investment:

  • Given an investment, it should be of a stock
  • Given an investment, it should have the invested shares' quantity
  • Given an investment, it should have the share price paid
  • Given an investment, it should have a cost

Using the standalone distribution downloaded in the previous chapter, the first thing we need to do is create a new spec file. This file can be created anywhere, but it is a good idea to stick to a convention, and Jasmine already has a good one: specs should be in the /spec folder. Create an InvestmentSpec.js file and add the following lines:

describe("Investment", function() {

});

The describe function is a global Jasmine function used to define test contexts. When used as the first call in a spec, it creates a new test suite (a collection of test cases). It accepts two parameters, which are as follows:

  • The name of the test suite—in this case, Investment
  • A function that will contain all its specs

Then, to translate the first acceptance criterion (given an investment, it should be of a stock) into a Jasmine spec (or test case), we are going to use another global Jasmine function called it:

describe("Investment", function() {
  it("should be of a stock", function() {

  });
});

It also accepts two parameters, which are as follows:

  • The title of the spec—in this case, should be of a stock
  • A function that will contain the spec code

To run this spec, add it to the runner, as follows:

<!-- include spec files here... -->
<script type="text/javascript" src="spec/InvestmentSpec.js"></script>

Execute the spec by opening the runner on the browser. The following output can be seen:

Jasmine basics and thinking in BDD

This is the first spec's passing result on the browser

It might sound strange to have an empty spec passing, but in Jasmine, as with other test frameworks, a failed assertion is required to make the spec fail.

An assertion (or expectation) is a comparison between two values that must result in a boolean value. The assertion is only considered a success if the result of the comparison is true.

In Jasmine, assertions are written using the global Jasmine function expect, along with a matcher that indicates what comparison must be made with the values.

Regarding the current spec (it is expected that the investment is of a stock), in Jasmine this translates to the following code:

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

Add the preceding highlighted code to the InvestmentSpec.js file. The expect function takes only one parameter, which defines the actual value, or in other words, what is going to be tested—investment.stock—and expects the chaining call to a matcher function, which in this case is toBe. That defines the expected value, stock, and the comparison method to be performed (to be the same).

Behind the scenes, Jasmine makes a comparison to check whether the actual value (investment.stock) and expected value (stock) are the same, and if they are not, the test fails.

With the assertion written, the spec that previously passed has now failed, as shown in the following screenshot:

Jasmine basics and thinking in BDD

This shows the first spec's failure results

This spec failed because, as the error message states, investment is not defined.

The idea here is to do only what the error is indicating us to do, so although you might feel the urge to write something else, for now let's just create this investment variable with an Investment instance in the InvestmentSpec.js file, as follows:

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

Don't worry that the Investment() function doesn't exist yet; the spec is about to ask for it on the next run, as follows:

Jasmine basics and thinking in BDD

Here the spec asks for an Investment class

You can see that the error has changed to Investment is not defined. It now asks for the Investment function. So, create a new Investment.js file in the src folder and add it to the runner, as shown in the following code:

<!-- include source files here... -->
<script type="text/javascript" src="src/Investment.js"></script>

To define Investment, write the following constructor function in the Investment.js file inside the src folder:

function Investment () {};

This makes the error change. It now complains about the missing stock variable, as shown in the following screenshot:

Jasmine basics and thinking in BDD

This shows a missing stock error

One more time, we feed the code it is asking for into the InvestmentSpec.js file, as shown in the following code:

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

The error changes again; this time it is about the missing Stock function:

Jasmine basics and thinking in BDD

Here the spec asks for a Stock class

Create a new file in the src folder, name it Stock.js, and add it to the runner. Since the Stock function is going to be a dependency of Investment, we should add it just before Investment.js:

<!-- include source files here... -->
<script type="text/javascript" src="src/Stock.js"></script>
<script type="text/javascript" src="src/Investment.js"></script>

Write the Stock constructor function to the Stock.js file:

function Stock () {};

Finally, the error is about the expectation, as shown in the following screenshot:

Jasmine basics and thinking in BDD

The expectation is undefined to be Stock

To fix this and complete this exercise, open the Investment.js file inside the src folder, and add the reference to the stock parameter:

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

In the spec file, pass stock as a parameter to the Investment function:

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

Finally, you will have a passing spec:

Jasmine basics and thinking in BDD

This shows an Investment spec that passes

This exercise was meticulously conducted to show how a developer works by feeding the spec with what it wants when doing test-first development.

Tip

The drive to write code must come from a spec that has failed. You must not write code unless its purpose is to fix a failed spec.

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

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