Max Max - 1 year ago 149
AngularJS Question

How to test _.defer() using Jasmine, AngularJs

I already asked this question where the main point was scope doesn't exists in terminal but it exists in Chrome debugging tool. Despite the answers it didn't get fixed.

The question is what is the right syntax to test the bellow directive, especially the line

. While digging through web i couldn't find any similar question most questions are related to
where in my case there is underscore method


'use strict';
.controller('MeasurementsTimelineCtrl', ['$scope', '$state', 'Measurements', function($scope, $state, Measurements) {
$scope.measurements = null;
var userId = $scope.currentUser ? $ : null;
if (userId) {
var listOfMeasurements = Measurements.userIndex(userId);
$scope.measurements = data;
$scope.$broadcast('measurements-updated', $scope.measurements);


'use strict';
.directive('dashboardMeasurementTimeline', ['$window', function($window) {
return {
restrict: 'E',
templateUrl: 'myView.html',
controller: 'MeasurementsTimelineCtrl',
link: function(scope, element){
scope.$on('measurements-updated', function(measurements) {
if(measurements) {
scope.measurementScroll = true;


'use strict';
describe('Directive: dashboardMeasurementTimeline', function () {

var $rootScope, $compile, element, scope;

beforeEach(function() {

inject(function($injector) {
$rootScope = $injector.get('$rootScope');
$compile = $injector.get('$compile');

scope = $rootScope.$new();
element = angular.element('<dashboard-measurement-timeline></dashboard-measurement-timeline>');
element = $compile(element)(scope);

scope.currentUser = {id : 'someId'};
scope.measurements = [{id: 'someId', time_of_test: 'Tue, 30 Dec 2014 14:00:00 -0000'},
{id: 'someId', time_of_test: 'Thu, 20 Nov 2014 03:00:00 -0000'},];
scope.$broadcast('measurements-updated', scope.measurements);

it('should assign true value to measurementScroll', function () {

Answer Source

You can do this by injecting a mock underscore library, with a defer function defined in the test. A way to do this is to define your own factory, _, which can then be mocked easily:

app.factory('_', function($window) {
  return $window._;

Then in the directive, you have to use it by injecting it:

app.directive('dashboardMeasurementTimeline', ['_', function(_) {

In the test, you can then mock it:

var deferCallback;
beforeEach(module(function($provide) {
  deferCallback = null;
  $provide.value('_', {
    defer: function(callback) {
      deferCallback = callback;

This means that instead of the real one, the directive will use the mock _, which saves the callback passed to defer as deferCallback so you can invoke it when needed:

scope.$broadcast('measurements-updated', scope.measurements);

This makes the test synchronous, which is usually a better idea than using done(), as it keeps test as fast as possible.

You can see the above working at

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download