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.
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").
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.
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.
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.
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.
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.
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.
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.
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();
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With