Click here to Skip to main content
15,886,035 members
Articles / All Topics

Writing JavaScript Tests Using Jasmine Framework

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
9 Oct 2016CPOL5 min read 8K   4  
In this post we will see how we can write unit test cases in JavaScript. Here we are going to use a framework called Jasmine to write and test our unit test cases. Jasmine is a behavior driven development framework to test our JavaScript codes.

In this post, we will see how we can write unit test cases in JavaScript. Here, we are going to use a framework called Jasmine to write and test our unit test cases. Jasmine is a behavior driven development framework to test our JavaScript codes. The interesting things about Jasmine framework are, it doesn’t even require a DOM, it is independent of any framework, clean and easy. Here, I will show you how we can create and run our JavaScript tests. I am going to use Visual Studio 2015 for the development. I hope you will like this article.

Background

As a developer, we all write JavaScript code for our client side development. Am I right? It is more important to check whether the codes we have written work well. So for that, we developers usually do unit testing. Few developers do manual testing to just check whether the functionality is working or not. But most of the MNCs have a set of rules to be followed while developing any functionalities, one of them is writing test cases. Once the test cases pass, then only you will be allowed to move your code to other environments. Here, I will show you how we can write client side test cases with the help of a framework called Jasmine.

Setting Up the Project

To get started, please create an empty project in your Visual Studio.

empty_project

Now, we will install jQuery, jQueryUI from Nuget package manager.

nuget_package_manager

We are all set to start our coding now.

Creating Page and Needed JS File

Next, we are going to create a page as shown below, with two text boxes and needed references.

HTML
<!DOCTYPE html>
<html>
<head>
    <title>Writing JavaScript test cases with Jasmine framework - Sibeesh Passion</title>
	<meta charset="utf-8" />
    <link href="Content/themes/base/jquery-ui.min.css" rel="stylesheet" />
    <link href="Content/themes/base/base.css" rel="stylesheet" />
    <script src="Scripts/jquery-3.1.1.min.js"></script>
    <script src="Scripts/jquery-ui-1.12.1.min.js"></script>
    <script src="Scripts/Index.js"></script>
</head>
<body>
    Start Date: <input type="text" name="name" value="" id="dtStartDate" />
    End Date: <input type="text" name="name" value="" id="dtEndDate" />
</body>
</html>

Now, we can start writing our JavaScript code in the file Index.js. We will start with a document ready function as follows:

JavaScript
$(function () {
    $("#dtStartDate").datepicker();
    $("#dtEndDate").datepicker();
    $("#dtEndDate").on("change leave", function () {        
    });
});

Shall we create our validation functions? We will be creating a namespace indexPage and functions. You can see the validations below.

JavaScript
var indexPage = {};
indexPage.validationFunctions = (function () {
    return {
        getStartDateSelectedValue: function () {
            return $("#dtStartDate").val();
        },
        getEndDateSelectedValue: function () {
            return $("#dtEndDate").val();
        },
        isNullValue: function (selVal) {
            if (selVal.trim() == "") {
                return true;
            }
            else {
                return false;
            }
        },
        isNullValueWithUIElements: function () {
            if (indexPage.validationFunctions.isNullValue
               (indexPage.validationFunctions.getStartDateSelectedValue())
            && indexPage.validationFunctions.isNullValue
               (indexPage.validationFunctions.getEndDateSelectedValue())) {
                alert("The values can't be null!.");
            }
        },
        isEndDateGreaterStart: function () {
            var startDate = new Date(indexPage.validationFunctions.getStartDateSelectedValue());
            var endDate = new Date(indexPage.validationFunctions.getEndDateSelectedValue());
            if (startDate < endDate) {
                return true;
            }
            else {
                alert("End date must be greater than start date!.")
                return false;
            }
        }
    }
}(jQuery));

Hope you are able to understand the code written. We wrote some validations like Null value check, end date greater than start date, etc.

Now, please run your application and check whether the validations are working fine.

null_validation_check

date_validation_check

Now, here comes the real part.

Setting Up Jasmine Framework

To set Jasmine, we will add a new project to our solution.

add_new_project

Now install Jasmine from Nuget Package manager.

jasmine_nuget_package

Once you are done, the required files would be added to your project. We will be discussing about Jasmine once everything is set. So no worries.

Now please add a new HTML file on your Jasmine project. This is the page where we can see the test cases in action, and add all the references as follows:

HTML
<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Jasmine Spec Runner - Sibeesh Passion</title>
    <link href="content/jasmine/jasmine.css" rel="stylesheet" />
    <script src="http://localhost:12387/Scripts/jquery-3.1.1.min.js"></script>
    <script src="http://localhost:12387/Scripts/jquery-ui-1.12.1.min.js"></script>
    <script src="scripts/jasmine/jasmine.js"></script>
    <script src="scripts/jasmine/jasmine-html.js"></script>
    <script src="scripts/jasmine/console.js"></script>
    <script src="scripts/jasmine/boot.js"></script>
    <script src="scripts/indextests.js"></script>
    <script src="http://localhost:12387/Scripts/Index.js"></script>
</head>
<body>

</body>
</html>

Please do not forget to include the js files where we actually wrote the validations, jquery, jqueryui (if needed). Here, indextests.js is the file where we are going to write the test cases.

Normally, this page is called as Spec Runner, Now you may be thinking what is a Spec? Before going further, there are some terms you must be aware of, there are listed below.

Suites

A suit is the starting point of a Jasmine test cases, it actually calls the global Jasmine function describe. It can have two parameters, a string value which describes the suit, and a function which implements the suit.

Spec

Like suites, a spec starts with a string which can be the title of the suit and a function where we write the tests. A spec can contain one or more expectation that test the state of our code.

Expectation

Value of an expectation is either true or false, an expectation starts with the function expect. It takes a value and calls the actual one.

You can always read more here. Now please run your SpecRunner.html page. If everything is fine, you can see a page as below.

jasmine_spec_runner_page

So are you all set? Shall we go and write our test cases? Please go to your IndexTest.js file and create a suit and spec as follows:

JavaScript
describe("Includes validations for index page", function () {
    var indexPage;
    beforeEach(function () {
        indexPage = window.indexPage.validationFunctions;
    });

    it("Check for null values", function () {
        // We are going to pass "" (null) value to the function
        var retVal = indexPage.isNullValue("");
        expect(retVal).toBeTruthy();
    });

});

Here, the expectation is true and we give toBeTruthy(). Now, let's go and find whether the test is passed or not. Please run the SpecRunner.html page again.

test_jasmine_specs

Now we will write test case for our function isEndDateGreaterStart. If you have noticed the function isEndDateGreaterStart, you can see that there are dependencies (UI elements). Inside of the function, we are getting the values from the UI elements.

JavaScript
var startDate = new Date(indexPage.validationFunctions.getStartDateSelectedValue());
var endDate = new Date(indexPage.validationFunctions.getEndDateSelectedValue());

So in this case, we need to mock these values. It is known as ‘Spy’ in Jasmine. We can use a function called SpyOn for this.

JavaScript
it("Spy call for datepicker date validation", function () {
    //Start date as 2015-03-25
    spyOn(indexPage, "getStartDateSelectedValue").and.returnValue("2015-03-25");
    //End date as 2015-03-24
    spyOn(indexPage, "getEndDateSelectedValue").and.returnValue("2015-03-24");
    var retVal = indexPage.isEndDateGreaterStart();
    expect(retVal).toBeFalsy();
});

Here, we are giving start date as 2015-03-25 and end date as 2015-03-24 and we know 2015-03-25 < 2015-03-24 is false, so here we are giving expectation as false (toBeFalsy()). Now you are getting an alert as follows right?

alert_in_spyon_jasmine

But in testing framework, we don’t need any alerts right? To get rid of this, you must create a spy for window.alert function and add it to the beforeEach so that it can be used for each specs. You can do that as follows:

JavaScript
window.alert = jasmine.createSpy("alert").and.callFake(function () { });

Once after you add this code, alert message won’t be thrown. Now please add another spec with true values (Start date – 2015-03-25, End date – 2015-03-26), so that it will return true.

JavaScript
it("Spy call for datepicker date validation toBeTruthy", function () {
      //Start date as 2015-03-25
      spyOn(indexPage, "getStartDateSelectedValue").and.returnValue("2015-03-25");
      //End date as 2015-03-26
      spyOn(indexPage, "getEndDateSelectedValue").and.returnValue("2015-03-26");
      var retVal = indexPage.isEndDateGreaterStart();
      expect(retVal).toBeTruthy();
  });

Now you can see all of your specs are passed.

run_all_specs_in_jasmine

Happy coding!

Conclusion

Did I miss anything that you think is needed? Could you find this post useful? I hope you liked this article. Please share your valuable suggestions and feedback.

Your Turn. What Do You Think?

A blog isn’t a blog without comments, but do try to stay on topic. If you have a question unrelated to this post, you’re better off posting it on C# Corner, Code Project, Stack Overflow, ASP.NET Forum instead of commenting here. Tweet or email me a link to your question there and I’ll definitely try to help if I can.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Germany Germany
I am Sibeesh Venu, an engineer by profession and writer by passion. I’m neither an expert nor a guru. I have been awarded Microsoft MVP 3 times, C# Corner MVP 5 times, DZone MVB. I always love to learn new technologies, and I strongly believe that the one who stops learning is old.

My Blog: Sibeesh Passion
My Website: Sibeesh Venu

Comments and Discussions

 
-- There are no messages in this forum --