Book Image

Jasmine Cookbook

By : Munish Kumar
Book Image

Jasmine Cookbook

By: Munish Kumar

Overview of this book

Table of Contents (16 chapters)
Jasmine Cookbook
Credits
About the Author
About the Reviewer
www.PacktPub.com
Preface
Index

Applying different matchers to the Jasmine test


Jasmine provides a rich set of matchers to test JavaScript code. In this recipe, you will learn to apply various matchers in different situations.

To understand this recipe, let's assume that you are developing an application and you have to implement test code for various scenarios by applying different Jasmine matchers.

"As a developer, I want to apply different Jasmine matchers so that I can implement a test condition successfully."

Let's consider some scenarios in the preceding context, that is, where Jasmine matchers should be applied for different test conditions:

  • Scenario-1: The 'toMatch' matcher should be applied successfully for regular expressions

  • Scenario-2: The 'toEqual' matcher should be applied successfully for literals, variables, and objects

  • Scenario-3: The 'toBe' matcher should be applied successfully for literals, variables, and objects

  • Scenario-4: The 'toBeDefined' matcher should be applied successfully to compares against defined

  • Scenario-5: The 'toBeUndefined' matcher should be applied successfully to compares against undefined

  • Scenario-6: The 'toBeNull' matcher should be applied successfully to compare against null

  • Scenario-7: The 'toBeTruthy' matcher should be applied successfully for Boolean casting testing

  • Scenario-8: The 'toBeFalsy' matcher should be applied successfully for Boolean casting testing

  • Scenario-9: The 'toContain' matcher should be applied successfully for finding an item in an array

  • Scenario-10: The 'toBeLessThan' matcher should be applied successfully for mathematical comparisons

  • Scenario-11: The 'toBeGreaterThan' matcher should be applied successfully for mathematical comparisons

  • Scenario-12: The 'toBeCloseTo' matcher should be applied for precision math comparison

How to do it…

To apply different matchers to your Jasmine tests, you need to perform the following steps in the preceding scenarios:

  1. Create the JasmineMatchers_spec.js file under the /spec folder and code the following lines:

    describe("Jasmine Matchers", function() {
    //Scenario – 1
      
    });
  2. Now, use the following code to define and implement the spec for scenario 1 using the toMatch matcher:

    describe("Jasmine Matchers",function(){
      //Scenario -1
      it("'toMatch' matcher should be applied successfully for regular expressions", function() {
          var strString1 = "Packt Cookbooks are an excellent source of learning";
          var strPhone = "001-789-56-67";
          expect(strString1).toMatch(/Cookbooks/);
          expect(strString1).toMatch(/cookbooks/i);
          expect(strString1).not.toMatch(/Java/);
          expect(strPhone).toMatch(/\d{3}-\d{3}-\d{2}-\d{2}/);
        });
    });

    Note

    A regular expression is a sequence of characters that forms a search pattern. Search patterns can be defined based on a single character, combination of characters/strings, or more complicated patterns. To explore more about regular expressions in greater depth, visit the following website:

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions

  3. The next step is to run the spec file (JasmineMatchers_spec.js) using the Jasmine runner, and you will see that the test passes, as shown in the following screenshot:

  4. Now, use following code to implement scenario 2 and scenario 3:

    describe("Jasmine Matchers",function(){
    
      //Scenario - 2
      describe("toEqual matcher should be applied successfully", function(){
        it("if numbers are equal", function() {
            var intVar = 15;
            expect(intVar).toEqual(15);
          });
        it("if strings are equal", function() {
            var strVar = "Jasmine Cookbook";    
            expect(strVar).toEqual("Jasmine Cookbook");
          });
    
        it("if objects are equal", function() {
            var MyObectj1 = {a: 12, b: 13};
            var MyObectj2 = {a: 12, b: 13};    
            expect(MyObectj1).toEqual(MyObectj2);
            expect(MyObectj1.a).toEqual(MyObectj2.a);
            expect(MyObectj1.a).not.toEqual(MyObectj2.b);
          });
        it("if arrays are equal", function() {
            expect([8, 9, 10]).toEqual([8, 9, 10]);
            expect([8, 9, 10, 11]).not.toEqual([8, 9, 10]);
          });
      });
    
      //Scenario - 3
      it("toBe matcher should be applied successfully for literals, variables and objects", function() {
          var MyObj = {foo: "foo"};
          var MySameObj = {foo: "foo"};
          var strVar = "Jasmine Cookbook";
          var myArr = [8, 9, 10];
          expect(MyObj).toBe(MyObj);
          expect(MySameObj).not.toBe(MyObj);
    
      expect(MySameObj).toEqual(MyObj);
          expect(strVar).toBe("Jasmine Cookbook");
          expect(myArr).toEqual([8, 9, 10]);
          expect(myArr).not.toBe([8, 9, 10]);
      });
    });

    In the preceding code snapshot, notice that we created two objects (that is, MyObj and MySameObj). Both look similar and equal, but they are two different objects with exactly the same attributes. Furthermore, you can observe the behavior of the toBe and toEqual matchers. Here, while comparing both the objects, the assertion value will return true with the toEqual matcher and false with the toBe matcher. Also, this is true for an array object (that is, myArr).

    Note

    The toEqual() matcher checks equivalence. On the other hand, the toBe() matcher ensures that they are the exact same objects.

  5. Next, run the spec file (JasmineMatchers_spec.js) for scenario 2 and scenario 3 using the Jasmine runner. The tests should run successfully, as shown in the following screenshot:

  6. Use the following code to implement scenario 4:

    describe("Jasmine Matchers",function(){
      //Scenario - 4
      it("toBeDefined should be applied successfully to compares against defined.", function() {
            var MyObj = {
              foo: "foo"
            };
            var Myfunction = (function() {})();
            var strUndefined;
            expect("Jasmine Cookbooks").toBeDefined();
            expect(MyObj).toBeDefined();
            expect(MyObj.foo).toBeDefined();
            expect(Myfunction).not.toBeDefined();
            expect(strUndefined).not.toBeDefined();
          
        });
    });

    Note

    Undefined is a built-in JavaScript type. In JavaScript, if we declare a variable without assigning a value, its type is undefined. Also, JavaScript functions without a return statement or with empty return statements return undefined. To learn more about undefined and how it works, visit the following website:

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined

  7. Use the following code to implement scenario 5:

    describe("Jasmine Matchers",function(){
      //Scenario - 5
      it("toBeUndefined should be applied successfully to compares against undefined.", function() {
          var MyObj = {
                  foo: "foo"
                };
          var Myfunction = (function() {})();
          var strUndefined;
            expect(MyObj).not.toBeUndefined();
            expect(MyObj.foo).not.toBeUndefined();      
            expect(Myfunction).toBeUndefined();
            expect(strUndefined).toBeUndefined();
      });
    });
  8. Now, run the spec file (for scenario 4 and 5) with the Jasmine runner. You will see that all Jasmine tests pass for both the scenarios, as shown in the following screenshot:

  9. To implement scenario 6, use the following code:

    describe("Jasmine Matchers",function(){
       //Scenario - 6
        it("toBeNull matcher should be applied successfully to compare against null", function() {
            var nullValue = null;
            var valueUndefined;
            var notNull = "notNull";
            expect(null).toBeNull();
            expect(nullValue).toBeNull();
            expect(valueUndefined).not.toBeNull();
            expect(notNull).not.toBeNull();
          });   
    });
  10. To see how Jasmine handles null values using the toBeNull matcher, run the spec file (only for scenario 6) with the Jasmine runner. You will see that the test passes, as shown in the following screenshot:

  11. Use the following code to implement scenarios 7 and 8:

    describe("Jasmine Matchers",function(){
        //Scenario - 7
           it("toBeTruthy matcher should be applied successfully for Boolean casting testing", function() {
            var MyVar1=12, MyVar2 = "True for Non Empty Strings";
            expect(true).toBeTruthy();
            expect("Jasmine Cookbook").toBeTruthy();
            expect(MyVar1).toBeTruthy();
            expect(MyVar2).toBeTruthy();
        });
        //Scenario - 8
        it("toBeFalsy matcher should be applied successfully for Boolean casting testing", function() {
            var MyVar1=12, MyVar2 = "True for Non Empty Strings";
            expect(false).toBeFalsy();
            expect(null).toBeFalsy();
            expect(true).not.toBeFalsy();
            expect("Jasmine Cookbook").not.toBeFalsy();
            expect(MyVar1).not.toBeFalsy();
            expect(MyVar2).not.toBeFalsy();
        });
    });
  12. Next, run the spec file (for scenarios 7 and 8) with the Jasmine runner and you will see that both the Jasmine tests pass, as shown in the following screenshot:

  13. Use the following code to implement scenario 9:

    describe("Jasmine Matchers",function(){
        it("toContain matcher should be applied successfully for finding an item in an Array", function() {
          var MyArray = ["Jasmine", "Cookbook", "JavaScript"];
            expect([1, 2, 3]).toContain(2);
            expect([1, 2, 3]).toContain(2,3);
            expect(MyArray).toContain("Cookbook");
            expect([1, 2, 3]).not.toContain(4);
            expect(MyArray).not.toContain("Java");
        });
    });
  14. Now, run the spec file (only for scenario 9) with the Jasmine runner and you will see that all the test conditions pass for scenario 9, as shown in the following screenshot:

  15. Use the following code to implement scenarios 10 and 11:

    describe("Jasmine Matchers",function(){
        //Scenario - 10
        it("toBeLessThan matcher should be applied successfully for mathematical comparisons", function() {
            var pi = 3.1415926, g = 9.71; num1=5, num2=9;
            expect(pi).toBeLessThan(g);
            expect(num1).toBeLessThan(num2);
            expect(g).not.toBeLessThan(pi);
            expect(num2).not.toBeLessThan(num1);
        });
    
        //Scenario - 11
        it("toBeGreaterThan matcher should be applied successfully for mathematical comparisons", function() {
            var pi = 3.1415926, g = 9.71; num1=5, num2=6;
            expect(g).toBeGreaterThan(pi);
            expect(num2).toBeGreaterThan(num1);
            expect(pi).not.toBeGreaterThan(g);
            expect(num1).not.toBeGreaterThan(num2);
        });
    });
  16. Run the spec file (for scenarios 10 and 11) with the Jasmine runner and you will see that both the tests pass, as shown in the following screenshot:

  17. To implement scenario 12, use the following code:

    describe("Jasmine Matchers",function(){
        it("toBeCloseTo matcher should be applied for precision math comparison", function() {
            var pi = 3.1415926, e = 2.78;
            expect(pi).not.toBeCloseTo(e);
            expect(pi).toBeCloseTo(e,0);
            expect(4.334).toBeCloseTo(4.334);
            expect(4.334).toBeCloseTo(4.3345,1);
            expect(4.334).toBeCloseTo(4.3345,2);
            expect(4.334).not.toBeCloseTo(4.3,2);
            expect(4.223).not.toBeCloseTo(4.22,3);
            expect(4.223).not.toBeCloseTo(4.22,4);
        });
    });
  18. Next, run the spec file (for scenario 12) with the Jasmine runner and you will see that all the test conditions pass:

  19. Finally, to run all the 12 scenarios in one go, make a single spec file with the entire test code and run it (JasmineMatchers_spec.js) with the Jasmine runner. You will see that all the tests pass:

How it works...

Let's take a look at the steps of this recipe.

In steps 1 to 3, we implemented scenario 1 with the toMatch matcher. It checks whether something is matched for a regular expression. You can use the toMatch matcher to test search patterns. In our case, we implemented the test code to find out search patterns with different regular expressions.

In steps 4 and 5, we defined the specs for scenario 2 and 3, and we implemented the test code corresponding to specs using the toEqual and toBe matchers. Here, notice that toBe looks similar to toEqual, but that is not the case. The toBe matcher returns the value true if the objects are equal. For example, in our case, MyObj and MySameObj look like the same objects, but in fact both are different objects with exactly the same attribute/behavior. Therefore, the assertion will return a true value with the toEqual matcher, but a false value with the toBe matcher.

In steps 6 to 8, we implemented scenarios 4 and 5 and saw how the toBeDefine and toBeUndefine matchers are applied to test JavaScript's Undefined type. In step 7, we first implemented a test condition for a non-empty string and two test conditions with object variable MyObj. We also implemented test conditions for the strUndefined variable and the MyFunction()function by applying negative assertions. Conversely, in step 8, we implemented test conditions with the object variable MyObj by applying negative assertions.

In step 9, we implemented test code for scenario 6 using the toBeNull matcher. In step 10, we saw test conditions pass for null values. However, we applied negative assertions to pass test conditions for not Null and Undefined values.

In step 11, we implemented scenario 7 and scenario 8 using the toBeTruthy and toBeFalsy matchers. We use the toBeTruthy matcher to check whether something returns/evaluates to true. Similarly, we use the toBeFalsy matcher to check whether something returns/evaluates to false. In our case, we applied the toBeTruthy matcher for true value, non-empty strings and numbers other than zero. Similarly, we applied toBeFalsy matcher to validate false, null, and empty strings.

In step 13, we implemented the test code for scenario 9 using the toContain matcher. Here, we implemented test conditions to find out an element(s)/item(s) of an array using the toContain matcher. Similarly, we implemented test conditions to check if an element/an item does did not exist in an array by applying negative assertions.

In step 15, we implemented scenario 10 and scenario 11 to compare mathematical values using the toBeLessThan and toBeGreaterThan matchers.

In step 17, we implemented scenario 12 using the toBeCloseTo matcher. This matcher is used to check whether a number is close to another number, up to a given level of decimal precision. In our case, we checked whether the expected number was equal to the actual number with a given level of decimal precision.