Writing your first Jasmine test

Before writing our first Jasmine test, we need to understand the difference between a suite and a spec (test specification) in Jasmine. Jasmine suite is a group of test cases that can be used to test a specific behavior of the JavaScript code. In Jasmine, the test suite begins with a call to the describe Jasmine global function that has two parameters. The first parameter represents the title of the test suite, while the second parameter represents a function that implements the test suite.

A Jasmine spec represents a test case inside the test suite. In Jasmine, the test case begins with a call to the Jasmine global function it that has two parameters. The first parameter represents the title of the spec and the second parameter represents a function that implements the test case.

A Jasmine spec contains one or more expectations. Every expectation represents an assertion that can be either true or false. In order to pass the specs, all of the expectations inside the spec have to be true. If one or more expectations inside a spec is false, then the spec fails. The following code listing shows an example of a Jasmine test suite and a spec with an expectation:

describe("A sample suite", function() {
    it("contains a sample spec with an expectation", function() {
        expect(true).toEqual(true);
    });
});

Let's move to the SimpleMath JavaScript object, which is described in the following code snippet. The SimpleMath JavaScript object is a simple mathematical utility that performs the mathematical operations: factorial, Signum, and average:

SimpleMath = function() {
};

SimpleMath.prototype.getFactorial = function (number) {
    
    if (number < 0) {
        throw new Error("There is no factorial for negative numbers");
    }
    else if (number == 1 || number == 0) {
        
        // If number <= 1 then number! = 1.
        return 1;
    } else {
    
        // If number > 1 then number! = number * (number-1)!
        return number * this.getFactorial(number-1);
    }    
}

SimpleMath.prototype.signum = function (number) {
    if (number > 0)  {
        return 1;
    } else if (number == 0) {
        return 0;
    } else {
        return -1;
    }
}

SimpleMath.prototype.average = function (number1, number2) {
    return (number1 + number2) / 2;
}

The SimpleMath object is used to calculate the factorial of numbers. In mathematics, the factorial of a non-negative integer n, denoted by n!, is the product of all the positive integers less than or equal to n, for example, 4! = 4 x 3 x 2 x 1 = 24.

The SimpleMath object calculates the factorial number using the getFactorial recursive function. It throws an error when the parameter passed to the getFactorial method is a negative number, because there is no factorial value for negative numbers.

Adding to calculating factorial, SimpleMath can get the Signum of any number using the signum method. In mathematics, the Signum function is a mathematical function that extracts the sign of a real number.

Finally, SimpleMath can calculate the average of two numbers using the average method. The average value of two numbers can be calculated by dividing the sum of the two numbers by 2.

Now, let's start writing the specs using Jasmine. First of all, in order to test the getFactorial method, let's look at the following three test scenarios. We will calculate the factorial of:

  • A positive number
  • Zero
  • A negative number

The following code snippet shows how to calculate the factorial of a positive number 3, zero, and a negative number -10:

describe("SimpleMath", function() {
    var simpleMath;
  
    beforeEach(function() {
        simpleMath = new SimpleMath();
    });

    describe("when SimpleMath is used to find factorial", function() {
        it("should be able to find factorial for positive number", function() {
            expect(simpleMath.getFactorial(3)).toEqual(6);
        });  
        it("should be able to find factorial for zero", function() {
            expect(simpleMath.getFactorial(0)).toEqual(1);
        });  

        it("should be able to throw an exception when the number is negative", function() {
            expect(
                function() { 
                    simpleMath.getFactorial(-10)
                }).toThrow();
        });         
    });   
    //...  
});

The describe keyword declares a new test suite called "SimpleMath". beforeEach is used for initialization of the specs inside the suite, that is, beforeEach is called once before the run of each spec in describe. beforeEach, simpleMath object is created using new SimpleMath().

In Jasmine, it is also possible to execute the JavaScript code after running each spec in describe using the afterEach global function. Having beforeEach and afterEach in Jasmine allows the developer not to repeat the set up and finalization code for each spec.

After initializing the simpleMath object, you can either create a direct spec using the "it" keyword or create a child test suite using the describe keyword. For the purpose of organizing the example, we create a new describe function for each group of tests with similar functionalities. This is why we create an independent "describe" function to test the functionality of getFactorial provided by the SimpleMath object.

In the first test scenario of the getFactorial test suite, the spec title is "should be able to find factorial for positive number", and the expect() function calls simpleMath.getFactorial(3) and expects it to be equal to 6. If simpleMath.getFactorial(3) returns a value other than 6, then the test fails.

We have many other options (matchers) to use instead of toEqual; we will show them in the Jasmine Matchers section.

In the second test scenario of the getFactorial test suite, the expect() function calls simpleMath.getFactorial(0) and expects it to be equal to 1. In the final test scenario of the getFactorial test suite, the expect() function calls simpleMath.getFactorial(-10) and expects it to throw an exception using the toThrow matcher. The toThrow matcher succeeds if the function of the expect() function throws an exception when executed.

After finalizing the getFactorial suite test, we come to a new test suite that tests the functionality of the signum method provided by the SimpleMath object, as shown in the following code snippet:

describe("when SimpleMath is used to find signum", function() {
    it("should be able to find the signum for a positive number", function() {
        expect(simpleMath.signum(3)).toEqual(1);
    });  

    it("should be able to find the signum for zero", function() {
        expect(simpleMath.signum(0)).toEqual(0);
    });  

    it("should be able to find the signum for a negative number", function() {
        expect(simpleMath.signum(-1000)).toEqual(-1);
    });
});

We have three test scenarios for the signum method. The first test scenario is getting the Signum of a positive number, the second test scenario is getting the Signum of zero, and the last test scenario is getting the Signum of a negative number. As validated by the specs, the signum method has to return 1 for a positive number (3), 0 for zero, and finally, -1 for a negative number (-1000). The following code snippet shows the average test suite:

describe("when SimpleMath is used to find the average of two values", function() {
    it("should be able to find the average of two values", function() {
          expect(simpleMath.average(3, 6)).toEqual(4.5);
    });
}); 

In the average spec, the test ensures that the average is calculated correctly by trying to calculate the average of two numbers, 3 and 6, and expecting the result to be 4.5.

Now, after writing the suites and specs, it is time to run our JavaScript tests. In order to run the tests, follow these steps:

  1. Place the simpleMath.js file in the src folder.
  2. Place the simpleMathSpec.js file in the spec folder.
  3. Edit the SpecRunner.html file, as shown by the highlighted code in the following code snippet:
    <!DOCTYPE HTML>
    <html>
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
            <title>Jasmine Spec Runner v2.0.0</title>
    
            <link rel="shortcut icon" type="image/png" href="lib/jasmine-2.0.0/jasmine_favicon.png">
            <link rel="stylesheet" type="text/css" href="lib/jasmine-2.0.0/jasmine.css">
    
            <script type="text/javascript" src="lib/jasmine-2.0.0/jasmine.js"></script>
            <script type="text/javascript" src="lib/jasmine-2.0.0/jasmine-html.js"></script>
            <script type="text/javascript" src="lib/jasmine-2.0.0/boot.js"></script>
    
            <!-- include source files here... -->
            <script type="text/javascript" src="src/simpleMath.js"></script>
    
            <!-- include spec files here... -->
            <script type="text/javascript" src="spec/simpleMathSpec.js"></script>
        </head>
        <body>
        </body>
    </html>

As shown in the highlighted lines, <script type="text/javascript" src="spec/simpleMathSpec.js"></script> is added under the include spec files omment , while <script type="text/javascript" src="src/simpleMath.js"></script> is added under the include source files comment. After clicking on the SpecRunner.html file, you will see our developed JavaScript tests succeed.

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

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