Rectangle 27 13

You have to trigger your own event passing a spy for the stopPropagation method, cause you wanna test if the event was stopped.

var event = {
    type: 'click',
    stopPropagation: function(){}
}
var spy = spyOn(event, 'stopPropagation');
$('#some_dom_element').trigger(event);
expect(spy).toHaveBeenCalled();

Note: there is code smell when you spy on the object you want to test, because you start to test the inner behavior of your class. Think about your function as a black box and test only the things you put in and get out. In your case, renaming the function in will break the test, while the code is still valid.

javascript - How to assert a spy is invoked with event on click using ...

javascript javascript-events jasmine jasmine-jquery
Rectangle 27 121

If you are defining your function:

function test() {};
window.test = function() {}  /* (in the browser) */
spyOn(window, 'test')

If that is not, you should also be able to:

If none of those are working, something else is going on with your setup.

I don't think your fakeElement technique works because of what is going on behind the scenes. The original globalMethod still points to the same code. What spying does is proxy it, but only in the context of an object. If you can get your test code to call through the fakeElement it would work, but then you'd be able to give up global fns.

It worked! I think the error I was making earlier was that I was calling the spyOn with method() instead of method. Thanks!

I've had some problems using spyOn(window, 'test') using chutzpah for running the tests as part of our automation due to 'window' not being assigned. Using jasmine.createSpy() got around this.

test = jasmine.createSpy();
$anchroScroll

For some reason I can't get either way to work, but it may be entirely possible that it's because I'm trying to mock up an existing window function; $window.open(url, '_blank'); with the intention of opening a new tab (or window depending on browser setup). How should I be going about making sure it's calling this function and verifying that it's navigating to the right url regardless of the browser?

javascript - Using Jasmine to spy on a function without an object - St...

javascript unit-testing jasmine
Rectangle 27 34

This one is not quite explicit because it seems that the function is actually a fake.

test = createSpy().and.callFake(test);
test = createSpy('testSpy', test).and.callThrough();

This makes a little more sense and breaks it out far enough to duplicate with success. +1 from me. Thanks, C

javascript - Using Jasmine to spy on a function without an object - St...

javascript unit-testing jasmine
Rectangle 27 13

I know the OP asked about javascript, but for any TypeScript users who come across this who want to spy on an imported function, here's what you can do.

In the test file, convert the import of the function from this:

import {foo} from '../foo_functions';

x = foo(y);
import * as FooFunctions from '../foo_functions';

x = FooFunctions.foo(y);
FooFunctions.foo
spyOn(FooFunctions, 'foo').and.callFake(...);
// ...
expect(FooFunctions.foo).toHaveBeenCalled();

Thanks for the TypeScript hint. Should be equally the same for ES6/Babel, but I haven't tried it.

Seems it only works if calling the function explicitly with the alias FooFunctions. I have a function bar() that is a factory returning baz() and want to test that baz() calls foo(). This method doesn't appear to work in that scenario.

This will work if the alias is taken inside foo_functions export const FooFunctions = { bar, foo }; and the import in the test becomes import { FooFunctions } from '../foo_functions'. However, the alias still needs to be explicitly used within foo_functions private implementation for the spy to work. const result = FooFunctions.foo(params) // spy reports call const result = foo(params) // spy reports no call

javascript - Using Jasmine to spy on a function without an object - St...

javascript unit-testing jasmine
Rectangle 27 2

Jasmine does not magically know which lines of your describe body you want reevaluated for each 'it' block.

javascript - Why is Jasmine not resetting a spy when spying on $.ajax?...

javascript ajax typescript jasmine spy
Rectangle 27 1

This may be a better way to do this. Add func as part of the Demo prototype. then you can hook up the spy to the prototype.

var Demo = function(option) {
  if (option) this.func();
}

Demo.prototype.func = function(){
    console.log("called")
}

beforeEach(function() {
    spyOn(Demo.prototype, 'func')
  var demo = new Demo(true);
  this.demo = demo;
});

it("should call func()", function() {
  expect(this.demo.func).toHaveBeenCalled();
});

Yea as you pointed out the function has already been called by the time you hook up the spy in your original question. Doing it with the prototype does have performance benefits. In your original question every time you make a new Demo object you get a new instance of func. with Demo.prototype.func all instances share this through the prototype.

javascript - Jasmine: How to properly spy on a function call? - Stack ...

javascript jasmine
Rectangle 27 8

I would suggest using jasmine.createSpyObj() when you want to mock objects with properties that need to be spied on.

myStub = jasmine.createSpyObj('myStub', ['setValue']);
spyOn(window, 'flipCounter').andReturn(myStub);

This tests interactions with the expected flipCounter interface, without depending on the flipCounter implementation.

I prefer this answer over @ggozad's answer, because it keeps external modules isolated from tests and uses a built-in jasmine utility designed specifically for mocking instance-like objects.

javascript - Spying on a constructor using Jasmine - Stack Overflow

javascript jasmine spy
Rectangle 27 1

it ('test myClass function', function() {
    myArgumentObject = function() {
        this.aMethod: jasmine.createSpy();
    };
    // mock out initial values for your other variables here, eg myVariable

    spyOn(vm, 'myFunction').andCallThrough();

    myClass(myArgumentObject)

    expect(myArgumentObject.aMethod).toHaveBeenCalled()
    expect(vm.myVariable).toEqual(2)
});

A couple things to keep in mind -- Your 'return vm' statement will cut your function off early -- you won't need it.

You should define your variables early so that you don't get an error. Consider moving myFunction above the 'vm' object.

Javascript unit testing - using Jasmine to spy on self-invoking functi...

javascript unit-testing jasmine
Rectangle 27 2

When you want to loop an array in javascript, you need to use javascript basic 'for loop' instead of 'for-in loop'.

The code in your validator factory should be like this.

for (var i = 0; i < rules.length; i++) {
    var rule = rules[i];
    if (!rule.isValid(post)) {
        return false;
    }
}

This got the first test to pass, thank you. I'm quite new to JS, so I was trying to use for...in like for each.

javascript - Jasmine unit test fails when spying on a service method -...

javascript angularjs unit-testing mocking jasmine
Rectangle 27 7

Daniel Smink's answer is correct, but note that the syntax has changed for Jasmine 2.0.

notify = jasmine.createSpy().and.callFake(function() {
  return false;
});

I also found it useful to just directly return a response if you only need a simple implementation

notify = jasmine.createSpy().and.returnValue(false);

javascript - How to spy on anonymous function using Jasmine - Stack Ov...

javascript angularjs testing jasmine karma-jasmine
Rectangle 27 21

The syntax for Jasmine 2 is different than 1.3 with respect to spy functions. See Jasmine docs here.

Specifically you reset a spy with spy.calls.reset();

// Source
var objectUnderTest = {
    someFunction: function (cb) {
        var promise = new Promise(function (resolve, reject) {
            if (true) {
                cb();
                resolve();
            } else {
                reject(new Error("something bad happened"));
            }
        });
        return promise;
    }
}

// Test
describe('foo', function () {
    it('tests', function (done) {
        var spy = jasmine.createSpy('mySpy');
        objectUnderTest.someFunction(spy).then(function () {
            expect(spy).toHaveBeenCalled();
            done();
        });
    });
    it('tests deeper', function (done) {
        var spy = jasmine.createSpy('mySpy');
        objectUnderTest.someFunction(spy).then(function () {
            expect(spy).toHaveBeenCalled();
            spy.calls.reset();
            return objectUnderTest.someFunction(spy);
        }).then(function () {
            expect(spy).toHaveBeenCalled();
            expect(spy.calls.count()).toBe(1);
            done();
        });
    });
});

Thanks! Apparently not all documentation is updated for the new version yet :(

javascript - Reset call on Jasmine spy does not return - Stack Overflo...

javascript jasmine spy jasmine2.0
Rectangle 27 3

You could chain your spy with andCallFake see:

andCallFake
//create a spy and define it to change notify
    notify = jasmine.createSpy().andCallFake(function() {
      return false;
    });

    it('should be a function', function() {
        expect(typeof notify).toBe('function');             
    });

    controller = createController();
    scope.isValid('name');
    expect(notify).toHaveBeenCalled();

javascript - How to spy on anonymous function using Jasmine - Stack Ov...

javascript angularjs testing jasmine karma-jasmine
Rectangle 27 1

Your spyOn() function returns a spy object - so I'me not sure why you are using mostRecentCall and the wrapper ?

var gapi = new Gapi(); // must create a variable to spy on.
var readySpy = spyOn(gapi, 'ready').andCallThrough();
// .. something that calls gapi.ready here
expect(readySpy).toHaveBeenCalled();

javascript - jasmine spy not called - Stack Overflow

javascript jasmine spy
Rectangle 27 4

You have to implement a fake constructor for flipCounter that sets the setValue property to a spy function. Let's say the function you want to test is this:

function flipIt() {
  var myFlipCounter = new flipCounter("counter", {inc: 23, pace: 500});
  myFlipCounter.setValue(100);
}
describe('flipIt', function () {
  var setValue;
  beforeEach(function () {
    setValue = jasmine.createSpy('setValue');
    spyOn(window, 'flipCounter').and.callFake(function () {
      this.setValue = setValue;
    });
    flipIt();
  });
  it('should call flipCounter constructor', function () {
    expect(window.flipCounter)
      .toHaveBeenCalledWith("counter", {inc: 23, pace: 500});
  });
  it('should call flipCounter.setValue', function () {
    expect(setValue).toHaveBeenCalledWith(100);
  });
});

javascript - Spying on a constructor using Jasmine - Stack Overflow

javascript jasmine spy
Rectangle 27 5

The Jasmine Clock api allows you to fake out the JavaScript Date functionality without manually writing a spy for it.

In particular, read the section about mocking the date.

describe("Mocking the Date object", function(){
    beforeEach(function() {
      jasmine.clock().install();
    });

    it("mocks the Date object and sets it to a given time", function() {
      var baseTime = new Date(2013, 9, 23);

      jasmine.clock().mockDate(baseTime);

      jasmine.clock().tick(50);
      expect(new Date().getTime()).toEqual(baseTime.getTime() + 50);
    });

    afterEach(function() {
      jasmine.clock().uninstall();
    });
});

angularjs - jasmine spyOn on javascript new Date - Stack Overflow

javascript angularjs unit-testing jasmine karma-jasmine
Rectangle 27 3

You could also use $provide to create a spy. And mock using and.returnValues instead of and.returnValue to pass in parameterised data.

As per Jasmine docs: By chaining the spy with and.returnValues, all calls to the function will return specific values in order until it reaches the end of the return values list, at which point it will return undefined for all subsequent calls.

describe('my fn', () => {
    beforeEach(module($provide => {
        $provide.value('externalApi', jasmine.createSpyObj('externalApi', ['get']));
    }));

        it('get userName and Id', inject((externalApi) => {
            // Given
            externalApi.get.and.returnValues('abc','123');

            // When
            //insert your condition

            // Then
            // insert the expectation                
        }));
});

This is the correct answer, since a test should always know exactly how a spy will be called, and therefore should just use returnValues to support multiple calls

javascript - Any way to modify Jasmine spies based on arguments? - Sta...

javascript unit-testing jasmine
Rectangle 27 1

When you spy on a function, you are actually stubbing the method. If you just want to check if the function was called but it's important that the content is executed, you need to add:

and.callThrough()
spyOn(this.view, 'close').and.callThrough();

And see if that helps you with your problem :)

I have tried this and the error remains "Expected spy close to have been called." - any other suggestions?

javascript - Jasmine expected spy function to have been called on back...

javascript jasmine jasmine-jquery gulp-jasmine
Rectangle 27 2

Consider the call to register a spy:

spyOn(test, 'bar').andCallThrough();

This creates a new spy function that does the spy work and then calls the spied function. The spy is then stored on the object in place of the original function. In your "without anonymous wrapper" example you register the event to call the function that is value of test.bar at the time the spy is registered:

$rootScope.$on('withoutFunctionWrapper', test.bar);

Whereas with the wrapper, the event will trigger whatever test.bar is set to at the time of the event, which in your case is the spy:

$rootScope.$on('withFunctionWrapper', function() {
  test.foo();
});

So you could try calling spyOn() first, if the function you're spying on can be made available before $rootScope.$on() is called. Otherwise, you'll need the wrapper.

javascript - Angular/Jasmine: spying on method passed to $rootScope.$o...

javascript angularjs jasmine karma-jasmine
Rectangle 27 1

Actually the way I went about it was over engineered. Just needed a closure. Did not need my custom setUpDeleteEventInAjax function

it('Deleting all the addresses should reveal the form', function () {
    var responses = [52670, 52671, 52672];
    var ajaxResponses = function () {
      return {
        status: true,
        id: responses.shift()
      }
    };
    spyOn($, 'ajax').and.callFake(ajaxResponses);

    $('#delete').click();
    expect($('.address-item').length).toEqual(4);

    $('#delete-2').click();
    expect($('.address-item').length).toEqual(2);
    expect($('.address-book')).toHaveClass('single-address');

    $('#delete-3').click();
    expect($('.address-item').length).toEqual(0);

  });
return { status: true, id: responses.shift() };
callCount

javascript - Jasmine, one test, multiple ajax requests ( error: ajax h...

javascript jquery ajax jasmine
Rectangle 27 2

If you look closely, you might realize that spyOn is replacing the original function with a spy that intercepts the function calls and tracks a lot of potentially useful information about them. The problem we run into above is that once weve replaced the original function, weve lost its capabilities. We can remedy that with andCallThrough. If you chain andCallThrough() after calling spyOn, the spy will then pass any calls to it through to the original function

javascript - Why spyOn "stops all execution of a function" in Jasmine ...

javascript documentation jasmine spyon