jasmine interview questions
Top jasmine frequently asked interview questions
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)
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?
mocha
chai
karma
jasmine
should.js
If anyone has more options to recommend, I would be happy to hear it.
Thanks!
Source: (StackOverflow)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)