Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test return value of a spy

I am developing an Ionic app. The calling function lets the user call the number in factory.call.

factory.call = '345-678-9087';

factory.calling = function(){
    return $window.location.href = 'tel:' + factory.call;
};

This is the Jasmine test for the above,

it('calling method', function(){
    spyOn(factory, 'calling');
    factory.calling();
    expect(typeof(windowMock.location.href)).toEqual('string');
});

The above test passes just fine, but it does not test the exact value that factory.calling() returns. I have tried the following with no luck.

1)

it('calling method', function(){
    var emergency = spyOn(factory, 'calling');
    factory.calling();
    expect(emergency).toEqual("'tel:' + factory.call");
});

2) spyOn(factory, "calling").andCallThrough().

3) spyOn(factory, "calling").andReturn("'tel:' + factory.call").

like image 380
Aaron Avatar asked May 02 '16 17:05

Aaron


People also ask

How do you use spyOn function?

spyOn() takes two parameters: the first parameter is the name of the object and the second parameter is the name of the method to be spied upon. It replaces the spied method with a stub, and does not actually execute the real method. The spyOn() function can however be called only on existing methods.

Why do we use spyOn?

spyOn() is inbuilt into the Jasmine library which allows you to spy on a definite piece of code.

What is callFake Jasmine?

callFake(fn)Tell the spy to call a fake implementation when invoked.

How do you test a function call in Jasmine?

With Jasmine async testing, we have to call the async code in the beforeEach() function that runs before each it() function block within a describe() function block. We also have to let Jasmine know when the async function has completed by calling the special done() callback function Jasmine provides.


2 Answers

Not sure you still need this, but call info contains "returnValue" property. So it can be tested like this: expect($scope.isFilterError.calls.first().returnValue).toBeFalsy();

like image 128
Maksim Gumerov Avatar answered Oct 16 '22 15:10

Maksim Gumerov


First, your factory is not returning anything:

factory.calling = function(){
    return $window.location.href = 'tel:' + factory.call;
};

Calls to $window.location.href that are an assignment will not return anything. Seems to me that that call should not be there and your method should be:

factory.calling = function(){
    return 'tel:' + factory.call;
};

Doing it this way, you have a return value. Also, you are not storing the value that is returned anywhere that you can test it. In general, you use a spy to check to see if the method was called, like this:

it('calling method', function(){
    spyOn(factory, 'calling');
    factory.calling();
    expect(factory.calling).toHaveBeenCalled();
});

To check what the method returns, you can call it within the expect block like this:

it('calling method', function(){
    expect(factory.calling()).toEqual('tel: ' + factory.call);
});

Or you can call it via an anonymous function like this:

it('calling method', function(){
    expect(function(){return factory.calling();}).toEqual('tel: ' + factory.call);
});

Or you can call it first and then check the value it returns like this:

it('calling method', function(){
    var result = factory.calling();
    expect(result).toEqual('tel: ' + factory.call);
});

I might also suggest that you test with fixed data that you provide since a test of this type should not be hitting a database. Also, you should always stick to OAPT (like you have done.)

like image 10
MBielski Avatar answered Oct 16 '22 14:10

MBielski