Running javascript and typescript unit tests in Microsoft Visual Studio 2012 with Chutzpah

To unit test my JavaScript files in Microsoft Visual Studio 2012, side by side mine C# unit tests, I use Chutzpah.

Chutzpah comes with 2 Microsoft Visual Studio 2012 extensions:

1. Chutzpah Test Adapter for Visual Studio 2012, allows you to run QUnit / Jasmine javascript test files side by side C# unit tests in the test explorer or continuous build process.

2. Chutzpah – A JavaScript Test Runner, allows you to run individual QUnit / Jasmine JavaScript test files in Microsoft Visual Studio 2010 and 2012 by right clicking a test file and choosing "".

 

In Microsoft Visual Studio 2012

– Tools > Extensions and Updates…

– Install both plugins and restart Microsoft Visual Studio 2012

 

image

 

Create a new UnitTest project:

 

image

 

Enable "Run Tests after build"

(The "Play" button found at the top of the Test Explorer")

Now when you press CTRL + SHIFT + B the project will be build and all tests will execute.

 

image 

 

TIP: Never use CTRL + S to save your file, just use CTRL + SHIFT + B.

Now you can see the C# unit test "TestMethod1" succeeded.

 

QUnit for ASP.NET MVC

Right click unit test project and click Manage NuGet Packages…

Click install.

 

image

 

Add Code.js and Test.js

The Code.js file will contain the JavaScript code we want to test.

The Test.js  file will contain the JavaScript test code written, by using the QUnit test framework.

 

Code.js

image

 

Test.js

Reference qunit and the Code.js file to get code completion in your test code.

 

image

 

Code completion in JavaScript in Microsoft Visual Studio 2012 unit test file

 

image

 

 

Run C# and JavaScript unit tests side by side in the Test Explorer

By pressing CTRL + SHIFT + B

image

 

Run only JavaScript unit test file

If you only want to run the QUnit test, right click on the JavaScript Test.js file and choose "Run JS Tests".

 

image

 

If you want to run JavaScript unit tests by pressing a keyboard shortcut, you need to install

image

 

Then you can bind a shortcut to the ProjectAndSolutionsContextMenus.Project.RunJSTests command to run JS tests.

(http://matthewmanela.com/blog/chutzpah-1-1-0-released/)

 

image

How to call a JavaScript function by string name.

An excellent answer to this question can be found at: http://stackoverflow.com/questions/359788/how-to-execute-a-javascript-function-when-i-have-its-name-as-a-string

I knew you could call a JavaScript function by it’s string name, by using window[‘functionName’], but this does not work for namespace functions.

When you want to call a namespace function by it’s string name you should use the namespace as context, instead of the window object.

<!DOCTYPE html>
<html>
<head>
    <title>General testpage.</title>
    <script src="/Scripts/Kendo/jquery.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        var MyApp = {};
        MyApp.Navigation = {};
        MyApp.Navigation.refreshDataSources = function ()
        {
            alert("Alert from refreshDataSources.");
        };

        // Dynamically calling namespace function by string name:
        MyApp.Navigation["refreshDataSources"]();

        // Dynamically get namespace part and calling a function in this namespace.
        MyApp["Navigation"]["refreshDataSources"]();            
    </script>
</head>
<body>
</body>
</html>

How to do JavaScript unit testing from C# with MSTest and JSTest

I wanted to run regular MSTest unit test written in C# to assert JavaScript code. There are several ways to accomplish this, but in this case I use JSTest.

Just add JSTest to your C# testproject with NuGet, now you can write tests like:

 

Test class

using JSTest;
using JSTest.ScriptLibraries;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TestProject1.Helpers;

namespace TestProject1
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            var script = new TestScript();

            // Arrange: Append the JavaScript code to test.
            string scriptContents = (new AssemblyHelper().GetContentsEmbededResourceFile("TestProject1.MvcApplication1.Scripts.Person.js"));
            script.AppendBlock(scriptContents);

            // Arrange: Append the JSTest asser library, so we can assert the test code.
            script.AppendBlock(new JsAssertLibrary());

            // Append "Act" JavaScript code.
            script.AppendBlock("var person1 = new Person('John Do', 32, 'Software Engineer');");

            // Assert.
            script.RunTest(@"assert.equal('Jonh Do test', person1.sayName());");
        }
    }
}

Running this test within Microsoft Visual Studio 2010 will result in a passed test.

 

JavaScript code to test

function Person(name, age, job)
{
    var privateField1 = 'test';
    this.name = name;
    this.age = age;
    this.job = job;
    this.privilegedMethod = function () { return privateField1; }
};

Person.prototype.sayName = function ()
{
    return this.name + ' ' + this.privilegedMethod();
};

Notes

– The privilegedMethod is used to access private fields on the Person class.

– You can set breakpoints in the JavaScript code!!

C# helper class

using System;
using System.IO;
using System.Reflection;

namespace TestProject1.Helpers
{
    public class AssemblyHelper
    {
        /// <summary>
        /// Read the contents of an embededresourcefile with the given name.
        /// </summary>
        /// <param name="resourceName">Name of the resource.</param>
        /// <returns></returns>
        public string GetContentsEmbededResourceFile(string resourceName)
        {
            if (string.IsNullOrWhiteSpace(resourceName)) { throw new ArgumentNullException("resourceName"); }

            string contents = string.Empty;
            using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
            using (var reader = new StreamReader(stream))
            {
                contents = reader.ReadToEnd();
            }
            return contents;
        }
    }
}

Microsoft Visual Studio 2010

image

How to add a CSS class to a HTML element, only when not present, by using jQuery.

You can add a CSS class to a HTML element, only when this class is not present on the HTML element, by using the jQuery function .toggleClass and using the switch parameter:

If your HTML page contains a div like:

<div id="title">
...
</div>

Adding the JavaScript code:

$(document).ready(function ()
{
    // The CSS class "titleStyling", will now be added, because it is does not exist on the title yet.
    $("#title").toggleClass("titleStyling", true);

    // Subsequent calls will not add extra classes, where the jQuery .addClass will.
    $("#title").toggleClass("titleStyling", true);

    // Subsequent calls will not add extra classes, where the jQuery .addClass will.
    $("#title").toggleClass("titleStyling", true);
});

Will result in

<div id="title" class="titleStyling">
...          
</div>

Solving the Error: ‘Sys’ is undefined in Microsoft Visual Studio 2010

If you create a new ASp.NET Web Application project in Microsoft Visual Studio 2010 and want to use the Sys.Debug function in an JavaScript function, you get the error ‘Sys’ is undefined. To solve this error, just drag and drop a ASP .NET scriptmanager from the toolbox on you’re master page, just below the form tag.

 

Example

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="Rvl.Demo.TrainingWebApplication.SiteMaster" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head runat="server">
    <title></title>
    <link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
    <asp:ContentPlaceHolder ID="HeadContent" runat="server">
    </asp:ContentPlaceHolder>
</head>
<body>
    <form runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <div class="page">
        <div class="header">
            <div class="title">
                <h1>
                    My ASP.NET Application
                </h1>
            </div>
            <div class="loginDisplay">
                <asp:LoginView ID="HeadLoginView" runat="server" EnableViewState="false">
                    <AnonymousTemplate>
                        [ <a href="~/Account/Login.aspx" ID="HeadLoginStatus" runat="server">Log In</a> ]
                    </AnonymousTemplate>
                    <LoggedInTemplate>
                        Welcome <span class="bold"><asp:LoginName ID="HeadLoginName" runat="server" /></span>!
                        [ <asp:LoginStatus ID="HeadLoginStatus" runat="server" LogoutAction="Redirect" LogoutText="Log Out" LogoutPageUrl="~/"/> ]
                    </LoggedInTemplate>
                </asp:LoginView>
            </div>
            <div class="clear hideSkiplink">
                <asp:Menu ID="NavigationMenu" runat="server" CssClass="menu" EnableViewState="false" IncludeStyleBlock="false" Orientation="Horizontal">
                    <Items>
                        <asp:MenuItem NavigateUrl="~/Default.aspx" Text="Home"/>
                        <asp:MenuItem NavigateUrl="~/About.aspx" Text="About"/>
                    </Items>
                </asp:Menu>
            </div>
        </div>
        <div class="main">
            <asp:ContentPlaceHolder ID="MainContent" runat="server"/>
        </div>
        <div class="clear">
        </div>
    </div>
    <div class="footer">
        
    </div>
    </form>
</body>
</html>

 

The Sys.Debug will now work:

 

image

 

 

 

 

 

‘Sys’ is undefined or ASP.NET Ajax client-side framework failed to load in a ASP .NET 4.0 website

I was getting the the error [‘Sys’ is undefined] and [ASP.NET Ajax client-side framework failed to load] in an ASP .NET 4.0 website. After reading and following the post [http://weblogs.asp.net/chrisri/archive/2007/02/02/demystifying-sys-is-undefined.aspx] I found my solution.

De ScriptResource.axd [long url] was throwing a 404 server error. This was caused by the fact that the website had an application pool set to .NET 4.0 but the [Handler Mappings] (see Screen dump 001) for the *.axd files where not registered. Even after executing the [aspnet_regiis –i –enable] the [Handler Mappings] where not registered. After re-creating the site, the error was resolved. The screen dump 002 shows the correct handler mappings.

 

Screen dump 001

image

 

Screen dump 002

image