Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Jasmine to spy on a function without an object

People also ask

How do you spy a function in Jasmine?

describe("Example Of jasmine Spy using Create Spy", function() { it("can have a spy function", function() { var person = new Person(); person. getName11 = jasmine. createSpy("Name spy"); person. getName11(); expect(person.

How do you spy on private property in Jasmine?

In Jasmine, you can do anything with a property spy that you can do with a function spy, but you may need to use different syntax. Use spyOnProperty to create either a getter or setter spy. it("allows you to create spies for either type", function() { spyOnProperty(someObject, "myValue", "get").

What is callThrough in Jasmine?

From Jasmine doc: By chaining the spy with and. callThrough, the spy will still track all calls to it but in addition it will delegate to the actual implementation.

What is Jasmine createSpy?

jasmine. createSpyObj is used to create a mock that will spy on one or more methods. It returns an object that has a property for each string that is a spy. If you want to create a mock you should use jasmine. createSpyObj .


If you are defining your function:

function test() {};

Then, this is equivalent to:

window.test = function() {}  /* (in the browser) */

So spyOn(window, 'test') should work.

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

test = jasmine.createSpy();

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.


TypeScript users:

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);

To this:

import * as FooFunctions from '../foo_functions';

x = FooFunctions.foo(y);

Then you can spy on FooFunctions.foo :)

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

There is 2 alternative which I use (for jasmine 2)

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

test = createSpy().and.callFake(test); 

The second more verbose, more explicit, and "cleaner":

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

-> jasmine source code to see the second argument


A very simple way:

import * as myFunctionContainer from 'whatever-lib';

const fooSpy = spyOn(myFunctionContainer, 'myFunc');

import * as saveAsFunctions from 'file-saver';
..........
....... 
let saveAs;
            beforeEach(() => {
                saveAs = jasmine.createSpy('saveAs');
            })
            it('should generate the excel on sample request details page', () => {
                spyOn(saveAsFunctions, 'saveAs').and.callFake(saveAs);
                expect(saveAsFunctions.saveAs).toHaveBeenCalled();
            })

This worked for me.


The approach we usually follow, is as follows:

utils.ts file for all global utilities:

function globalUtil() {
  // some code
}

abc.component.ts:

function foo {
  // some code
  globalUtil();  // calls global function from util.ts
}

While writing a Jasmine test for function foo (), you can spy on the globalUtil function as follows:

abc.component.spec.ts:

import * as SharedUtilities from 'util.ts';

it('foo', () =>
{
  const globalUtilSpy = jasmine.createSpy('globalUtilSpy');
  spyOnProperty(SharedUtilities, "globalUtilSpy").and.returnValue(globalUtilSpy);
  
  foo();
  expect(globalUtilSpy).toHaveBeenCalled();
});