Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get Jasmine's spyOnProperty to work?

I saw this post post and was excited to try it out, but I'm unable to get it working. Trying to keep this simple just to figure out what's wrong, but even this is failing.

export class SomeService {
...
private _myValue: Boolean = false;
get myValue(): Boolean {
    return this._myValue;
}
set myValue(helper: Boolean) {
    this._myValue = helper;
}

And in my unit test, I have:

 it('should ', inject([SomeService], (someService: SomeService) => {         
    let oldValue = someService.myValue;    
    expect(oldValue).toBe(false); // passes, clearly we can use our getter
    someService.myValue = true;    
    expect(someService.myValue).toBe(true); // passed, clearly the setter worked

    spyOnProperty(someService, 'myValue', 'getter').and.returnValue(false); // Property myValue does not have access type getter

    //spyOnProperty(someService, 'myValue', 'get').and.returnValue(false);same error if tried this way

    expect(someService.myValue).toBe(false);
 }));

I put the values up top to clearly show I can get and set the value. That has no problems. Wallaby shows ReferenceError: spyOnProperty is not defined on the spyOnProperty line. I'm not sure if that helps, but the errors I put above were what karma gives me when I run those tests.

Anyone who has gotten this to work, I'd greatly appreciate the assistance. Apologies for any typos, I've been staring at this for most of the day.

like image 449
Angelo Avatar asked May 12 '17 02:05

Angelo


People also ask

How do I spy on object 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").

How do you mock a function in Jasmine?

Using Jasmine spies to mock code Jasmine spies are easy to set up. You set the object and function you want to spy on, and that code won't be executed. In the code below, we have a MyApp module with a flag property and a setFlag() function exposed. We also have an instance of that module called myApp in the test.

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 can you do with a property spy 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. Changing the value of an existing spy is more difficult than with a function, because you cannot refer to a property without calling its getter method.

What is spyon () function in Jasmine?

Jasmine Spies: The spyOn() Function Jasmine Spies: spyOn(), and.callThrough(), and.returnValue(), and.callFake() Test doubles like mocks, spies, and stubs are integral part of unit testing. In Jasmine, there are few such functions which can stub any function and track calls to it and all its arguments. They are known as spies.

How can Jasmine spy on a getter?

The point of a getter is that it acts exactly like a property, so how would jasmine be able to spy on it when it is never called like a function but rather is accessed like a property. As a workaround, you could have your getter call another function and spy on that instead.

Why can't I use spyonproperty on a property?

That probably means you can't use it on that property. spyOnProperty is using getOwnPropertyDescriptor and checking if the access type get|set for that property descriptor exists. The error you are getting is because the property descriptor is not set or get for the property you are trying to spy on.


2 Answers

Well I spent way more time on this then I care to admit, but the answer ended up being a simple syntactical error:

The correct value to use as the 3rd parameter is get, not getter as I had been. For example:

spyOnProperty(someService, 'myValue', 'get').and.returnValue(false)

Which I did try early on, but did not work at the time. I'm not sure what changed. I also updated @types/jasmine, along with everything else in my dev library to @latest, but I didn't restart the IDE afterward because I didn't think it'd matter. I can only guess that's why it works now.

like image 97
Angelo Avatar answered Oct 20 '22 08:10

Angelo


I was still struggling a bit to get the set to work.

const foo = {
  get value() {},
  set value(v) {}
};

it('can spy on getters', () => {
  spyOnProperty(foo, 'value', 'get').and.returnValue(1);
  expect(foo.value).toBe(1);
});

it('and on setters', () => {
  const spiez = spyOnProperty(foo, 'value', 'set');
  foo.value = true;
  expect(spiez).toHaveBeenCalled();
});
like image 11
Laoujin Avatar answered Oct 20 '22 07:10

Laoujin