4

I'm trying to run some JavaScript code using jasmine and Resharper 7 within visual studio 2012. I follow the AMD pattern with the aid of requirejs. However, i haven't managed to make my test run in the Resharper test runner.

Has anyone managed to do anything similar to that?

ppoliani
  • 4,792
  • 3
  • 34
  • 62
  • The problem is that requirejs runs the code after it has asynchronously loaded the modules, during this time the page loads correctly and Jasmine records that there are no tests run and has finished, Resharper then kills the process and reports the results. To sum it up the requirejs modules are not loaded\executed before the process is terminated. This is a common problem with Resharper, Chutzpah, Karma and other runners when used with requirejs. – Mark Broadhurst May 01 '13 at 09:42

3 Answers3

5

Use a named requireJS Module

define("my/sut", function () {

    var MySut = function () {
        return {
            answer: 42
        };
    };
    return MySut;
});

And initialize the SUT with the asyncronus support of Jasmine. Don't forgot the references!

/// <reference path="~/Scripts/require.js"/>
/// <reference path="../code/sut.js" />

describe("requireJS with Jasmine and Resharper", function () {

    it("should be executed", function () {

        // init SUT async
        var sut;
        runs(function () {
            require(['my/sut'], function (MyModel) {
                sut = new MyModel();
            });
        });
        waitsFor(function () {
            return sut;
        }, "The Value should be incremented", 100);

        // run the test
        runs(function () {
            expect(sut.answer).toBe(42);
        });
    });
});

I hope this works with more modules. In my case it worked with waitsFor '0' ms.

mgsdev
  • 51
  • 1
  • 3
  • 1
    Using named modules and referencing them kind of defeats the purpose of using require. If I do this, not only do I have the module name duplicated in the filename and the code, but I also have to reference all modules involved. – Thomas Eyde Mar 13 '14 at 15:34
1

A simplified version of mgsdev response, put the loading code in a beforeEach statement, that way you can write short expectations.

module:

define("stringCalculator", function () {
    return {
        calculate: function (string) {
            var result = 0;
            string.split("+").forEach(function(number) {
                result += parseInt(number);
            });
            return result;
        }
    };
});

test file: if calculator is undefined it will try to load it before every expectation.

/// <reference path="~/Scripts/require.js"/>
/// <reference path="~/code/stringCalculator.js"/>

describe("string calculator", function () {
    var calculator;

    beforeEach(function () {    
        if (!calculator) {
            require(["stringCalculator"], function (stringCalculator) {
                calculator = stringCalculator;
            });

            waitsFor(function () {
                return calculator;
            }, "loading external module", 1000);
        }
    });

    it("should add 1 and 2", function () {
        var result = calculator.calculate("1+2");
        expect(result).toEqual(3);
    });

    it("should add 2 and 2", function () {
        var result = calculator.calculate("2+2");
        expect(result).toEqual(4);
    });

    it("should add 1, 2 and 3", function() {
        var result = calculator.calculate("1+2+3");
        expect(result).toEqual(6);
    });
});
Beelphegor
  • 226
  • 1
  • 12
0

If you use Jasmine 2.0 or newer, you can support asynchronous calls in your code. Just pass the done parameter into the function for your it unit test, then call done() when you have loaded your modules:

describe("add function", function(){
   it("calls renderNew", function(done){
      define("taskRenderer", [], function() {
         return {
            renderNew: function(){}
         };
      });

      require(["taskRenderer"], function(taskRenderer) {
         spyOn(taskRenderer, "renderNew");
         taskRenderer.renderNew();
         expect(taskRenderer.renderNew).toHaveBeenCalled();
         done();
      });
   }
}

This way, you don't actually perform your test until the modules are loaded and the test doesn't prematurely get marked as finished.

Matt Zappitello
  • 785
  • 2
  • 11
  • 30