EzDevInfo.com

jasmine interview questions

Top jasmine frequently asked interview questions

Jasmine.js comparing arrays

Is there a way in jasmine.js to check if two arrays are equal, for example:

arr = [1, 2, 3]
expect(arr).toBe([1, 2, 3])
expect(arr).toEqual([1, 2, 3])

Neither seems to work.


Source: (StackOverflow)

What are the differences between mocha, chai, karma, jasmine, should.js, etc. testing frameworks?

I'm new to testing, and I see that there are many options to work with and I'm confused.

I would like to know the differences between the following frameworks, especially what service each framework provides, and why we need so many frameworks to have one flow of testing?

  1. mocha

  2. chai

  3. karma

  4. jasmine

  5. should.js

If anyone has more options to recommend, I would be happy to hear it.

Thanks!


Source: (StackOverflow)

Advertisements

Jasmine - How to write a test which expects an Error to be thrown

I'm trying to write a test for the Jasmine Test Framework which expects an error. At the moment I'm using a Jasmine Node.js integration from GitHub.

In my Node module I have the following code:

throw new Error("Parsing is not possible");

Now I try to write a test which expects this error:

describe('my suite...', function() {
    [..]
    it('should not parse foo', function() {
    [..]
        expect(parser.parse(raw)).toThrow(new Error("Parsing is not possible"));
    });
});

I tried also Error() and some other variants and just can't figure out how to make it work.


Source: (StackOverflow)

Unit-testing directive controllers in Angular without making controller global

In Vojta Jina's excellent repository where he demonstrates testing of directives, he defines the directive controller outside of the module wrapper. See here: https://github.com/vojtajina/ng-directive-testing/blob/master/js/tabs.js

Isn't that bad practice and pollute the global namespace?

If one were to have another place where it might be logical to call something TabsController, wouldn't that break stuff?

The tests for the mentioned directive is to be found here: https://github.com/vojtajina/ng-directive-testing/commit/test-controller

Is it possible to test directive controllers separate from the rest of the directive, without placing the controller in a global namespace?

It would be nice to encapsulate the whole directive within the app.directive(...) definition.


Source: (StackOverflow)

Any way to modify Jasmine spies based on arguments?

I have a function I'd like to test which calls an external API method twice, using different parameters. I'd like to mock this external API out with a Jasmine spy, and return different things based on the parameters. Is there any way to do this in Jasmine? The best I can come up with is a hack using andCallFake:

var functionToTest = function() {
  var userName = externalApi.get('abc');
  var userId = externalApi.get('123');
};


describe('my fn', function() {
  it('gets user name and ID', function() {
    spyOn(externalApi, 'get').andCallFake(function(myParam) {
      if (myParam == 'abc') {
        return 'Jane';
      } else if (myParam == '123') {
        return 98765;
      }
    });
  });
});

Source: (StackOverflow)

How do you mock a service in AngularJS when unit testing with jasmine?

Let's say I have a service shop that depends on two stateful services schedule and warehouse. How do I inject different versions of schedule and warehose into shop for unit testing?

Here's my service:

angular.module('myModule').service('shop', function(schedule, warehouse) {
    return {
        canSellSweets : function(numRequiredSweets){
             return schedule.isShopOpen()
                 && (warehouse.numAvailableSweets() > numRequiredSweets);
        }
    }
});

Here are my mocks:

var mockSchedule = {
    isShopOpen : function() {return true}
}
var mockWarehouse = {
    numAvailableSweets: function(){return 10};
}

Here are my tests:

expect(shop.canSellSweets(5)).toBe(true);
expect(shop.canSellSweets(20)).toBe(false);

Source: (StackOverflow)

How can I get WebStorm to recognize Jasmine methods?

I have a node.js project that contains some Jasmine specifications. The specifications are in a spec/ subdirectory and have the .spec.coffee extension, as required by jasmine-node.

When I open one of my spec files in the WebStorm IDE, all the calls to beforeEach and describe and it are shown with blue squiggly underlines with the tooltip: "Unresolved function or method it()". So even though I'm using the 3.0 EAP and it's supposed to have some amount of Jasmine support, it's not automatically picking up on the fact that this is a Jasmine spec file.

I tried going into File > Settings > JavaScript Libraries, and adding Jasmine as a library (specifying the path to jasmine-2.0.0.rc1.js), and then going to the Usage Scope sub-page and checking "Jasmine" in the drop-down list next to "Project", but that had no effect -- the Jasmine methods still show up as unresolved.

How can I tell WebStorm that all files in a spec subdirectory, and/or all files with a .spec.coffee extension, are Jasmine tests, and have it recognize the Jasmine APIs those tests are using?


Source: (StackOverflow)

Unit testing AngularJS factories that have dependencies

When unit testing an Angular factory (with Karma + Jasmine), how do I inject a stub dependency into the factory under test?

Here's my factory:

mod = angular.module('myFactoryMod', []);

mod.factory('myFactory', [
  '$log', 'oneOfMyOtherServices', function($log, svc) {
    return makeSomethingThatDoesSomethingWithTheseDependencies($log, svc);
  }
]);

oneOfMyOtherServices is needed when instantiating my factory.

Here's my test:

it('can get an instance of my factory', function() {
  var oneOfMyOtherServicesStub;

  angular.mock.module('myFactoryMod');

  oneOfMyOtherServicesStub = {
    someVariable: 1
  };

  //****How do I get my stub in my target? ****

  angular.mock.inject(['myFactory', function(target) {

      expect(target).toBeDefined();

    }
  ]);
})

N.B. I know that $controller allows this for controllers, but I don't see an equivalent for factories.


Source: (StackOverflow)

Mocking Angular module dependencies in Jasmine unit tests

I'm attempting to unit test controller code inside a module that takes other modules as dependencies, but haven't been able to figure out how to mock them properly.

I'm using the Jasmine Framework and running my tests with Karma (Testacular).

Module Code

var app = angular.module('events', ['af.widgets', 'angular-table']);

app.controller('eventsCtrl', function([dependencies]){
    $scope.events = [];
    ...
});

Spec Code

describe('events module', function(){
    var $scope,
        ctrl;

    beforeEach(function(){
        angular.mock.module('af.widgets', []);
        angular.mock.module('angular-table', []);
        module('events', ['af.widgets', 'angular-table']);
    });

    beforeEach(inject(function($rootScope, $controller){
        $scope = $rootScope.new();
        ctrl = $controller('NameCtrl', {
            $scope: $scope,
        });
    }));

    it('should have an empty events array', function(){
        expect($scope.events).toBe([]);
    })
});

The error I'm getting is Karma is "no module af.widgets", so obviously I'm not mocking the module dependencies right. Any hints?


Source: (StackOverflow)

Getting requirejs to work with Jasmine

I first want to say that I am new to RequireJS and even newer to Jasmine.

I am having some issues with the SpecRunner and require JS. I have been following the tutorials of Uzi Kilon and Ben Nadel (along with some others) and they helped some but I am still having some issues.

It seems that, if there is an error that is thrown in the test (I can think of one in particular, a type error) the spec runner html will display. This tells me that I have some issues in the javascript. However, after I fix those error no HTML is displayed anymore. I cannot get the test runner to display at all. Can someone find something wrong with my code that would cause this issue?

Here is my directory structure:

Root 
|-> lib
    |-> jasmine
        |-> lib (contains all of the jasmine lib)
        |-> spec
        |-> src
    |-> jquery (jquery js file)
    |-> require (require js file) 
index.html (spec runner) specRunner.js

Here is the SpecRunner (index) HTML:

<!doctype html>
<html lang="en">
    <head>
        <title>Javascript Tests</title>

        <link rel="stylesheet" rel='nofollow' href="lib/jasmine/lib/jasmine.css">

        <script src="lib/jasmine/lib/jasmine.js"></script>
        <script src="lib/jasmine/lib/jasmine-html.js"></script>
        <script src="lib/jquery/jquery.js"></script>
        <script data-main="specRunner" src="lib/require/require.js"></script>

        <script>
            require({ paths: { spec: "lib/jasmine/spec" } }, [
                    // Pull in all your modules containing unit tests here.
                    "spec/notepadSpec"
                ], function () {
                    jasmine.getEnv().addReporter(new jasmine.HtmlReporter());
                    jasmine.getEnv().execute();
                });
        </script>

    </head>

<body>
</body>
</html>

Here is the specRunner.js (config)

require.config({
    urlArgs: 'cb=' + Math.random(),
    paths: {
        jquery: 'lib/jquery',
        jasmine: 'lib/jasmine/lib/jasmine',
        'jasmine-html': 'lib/jasmine/lib/jasmine-html',
        spec: 'lib/jasmine/spec/'
    },
    shim: {
        jasmine: {
            exports: 'jasmine'
        },
        'jasmine-html': {
            deps: ['jasmine'],
            exports: 'jasmine'
        }
    }
});

Here is a spec:

require(["../lib/jasmine/src/notepad"], function (notepad) {
    describe("returns titles", function() {
        expect(notepad.noteTitles()).toEqual("");


    });
});

The notepad source:

define(['lib/jasmine/src/note'], function (note) {

    var notes = [
        new note('pick up the kids', 'dont forget to pick  up the kids'),
        new note('get milk', 'we need two gallons of milk')
    ];


    return {
        noteTitles: function () {
            var val;

            for (var i = 0, ii = notes.length; i < ii; i++) {
                //alert(notes[i].title);
                val += notes[i].title + ' ';
            }

            return val;
        }
    };
});

And the Note source (JIC):

define(function (){
    var note = function(title, content) {
        this.title = title;
        this.content = content;
    };

    return note;
});

I have made sure that, as far as the app is concerned, the paths are correct. Once I get this working I can play with configuring that paths so that it isn't so yucky.


Source: (StackOverflow)

What does the underscores in _servicename_ mean in AngularJS tests?

In the following example test, the original provider name is APIEndpointProvider, but for injection and service instantiation the convention seems to be it has to be injected with underscores wrapping it. Why is that?

'use strict';

describe('Provider: APIEndpointProvider', function () {

  beforeEach(module('myApp.providers'));

  var APIEndpointProvider;
  beforeEach(inject(function(_APIEndpointProvider_) {
    APIEndpointProvider = _APIEndpointProvider_;
  }));

  it('should do something', function () {
    expect(!!APIEndpointProvider).toBe(true);
  });

});

What is the convention I'm missing a better explanation to?


Source: (StackOverflow)

How to Unit Test Isolated Scope Directive in AngularJS

What is a good way to unit test isolated scope in AngularJS

JSFiddle showing unit test

Directive snippet

    scope: {name: '=myGreet'},
    link: function (scope, element, attrs) {
        //show the initial state
        greet(element, scope[attrs.myGreet]);

        //listen for changes in the model
        scope.$watch(attrs.myGreet, function (name) {
            greet(element, name);
        });
    }

I want to ensure the directive is listening for changes - this does not work with an isolated scope:

    it('should watch for changes in the model', function () {
        var elm;
        //arrange
        spyOn(scope, '$watch');
        //act
        elm = compile(validHTML)(scope);
        //assert
        expect(scope.$watch.callCount).toBe(1);
        expect(scope.$watch).toHaveBeenCalledWith('name', jasmine.any(Function));
    });

UPDATE: I got it to work by checking if the expected watchers were added to the child scope, but it's very brittle and probably using the accessors in an undocumented way (aka subject to change without notice!).

//this is super brittle, is there a better way!?
elm = compile(validHTML)(scope);
expect(elm.scope().$$watchers[0].exp).toBe('name');

UPDATE 2: As I mentioned this is brittle! The idea still works but in newer versions of AngularJS the accessor has changed from scope() to isolateScope():

//this is STILL super brittle, is there a better way!?
elm = compile(validHTML)(scope);                       
expect(elm.isolateScope().$$watchers[0].exp).toBe('name');

Source: (StackOverflow)

How do I mock a service that returns promise in Angularjs Jasmine unit test?

I have myService that uses myOtherService, which makes a remote call, returning promise:

angular.module('app.myService', ['app.myOtherService'])
  .factory('myService', [myOtherService,

    function(myOtherService) {
      function makeRemoteCall() {
        return myOtherService.makeRemoteCallReturningPromise();
      }

      return {
        makeRemoteCall: makeRemoteCall
      };      
    }
  ])

To make a unit test for myService I need to mock myOtherService, such that its makeRemoteCallReturningPromise() method returns a promise. This is how I do it:

describe('Testing remote call returning promise', function() {
  var myService;
  var myOtherServiceMock = {};

  beforeEach(module('app.myService'));

  // I have to inject mock when calling module(),
  // and module() should come before any inject()
  beforeEach(module(function ($provide) {
    $provide.value('myOtherService', myOtherServiceMock);
  }));

  // However, in order to properly construct my mock
  // I need $q, which can give me a promise
  beforeEach(inject( function(_myService_, $q){
    myService = _myService_;
    myOtherServiceMock = {
      makeRemoteCallReturningPromise: function() {
        var deferred = $q.defer();
        deferred.resolve('Remote call result');
        return deferred.promise;
      }    
    };
  }

  // Here the value of myOtherServiceMock is not
  // updated, and it is still {}
  it('can do remote call', inject(function() {
    myService.makeRemoteCall() // Error: makeRemoteCall() is not defined on {}
      .then(function() {
        console.log('Success');
      });    
  }));  

As you can see from the above, the definition of my mock depends on $q, which I have to load using inject(). Furthermore, injecting the mock should be happening in module(), which should be coming before inject(). However, the value for mock is not updated once I change it.

What is the proper way to do this?


Source: (StackOverflow)

Injecting a mock into an AngularJS service

I have an service AngularJS service written and would like to unit test it.

angular.module('myServiceProvider', ['fooServiceProvider', 'barServiceProvider']).
    factory('myService', function ($http, fooService, barService) {

    this.somthing = function() {
        // Do something with the injected services
    };

    return this;
});

My app.js file has these registered:

angular
.module('myApp', ['fooServiceProvider','barServiceProvider','myServiceProvider']
)

I can test the DI is working as such:

describe("Using the DI framework", function() {
    beforeEach(module('fooServiceProvider'));
    beforeEach(module('barServiceProvider'));
    beforeEach(module('myServiceProvder'));

    var service;

    beforeEach(inject(function(fooService, barService, myService) {
        service=myService;
    }));

    it("can be instantiated", function() {
        expect(service).not.toBeNull();
    });
});

This proved that the service can be created by the DI framework, however next I want to unit test the service, which means mocking out the injected objects.

How do I go about doing this?

I've tried putting my mock objects in the module, e.g.

beforeEach(module(mockNavigationService));

and rewriting the service definition as:

function MyService(http, fooService, barService) {
    this.somthing = function() {
        // Do something with the injected services
    };
});

angular.module('myServiceProvider', ['fooServiceProvider', 'barServiceProvider']).
    factory('myService', function ($http, fooService, barService) { return new MyService($http, fooService, barService); })

But the latter seems to stop the service being created by the DI as all.

Does anybody know how I can mock the injected services for my unit tests?

Thanks

David


Source: (StackOverflow)

How can I test events in angular?

I need to test that events get correctly emitted or broadcasted, and trigger events manually.

What's the best way to do this?


Source: (StackOverflow)