The service
...
export class MyService {
...
get serviceProperty(){
return this.browserStorageService.retrieve('value');
}
set serviceProperty(value){
this.browserStorageService.store('value', value);
}
...
}
In the component
...
export Class Component implements OnInit {
...
constructor(private myService: MyService){}
ngOnInit(){
subscribeToWhatever();
}
private subscribeToWhatever(){
...
if(!this.myService.serviceProperty){
console.log('before', this.myService.serviceProperty); *//logs null*
this.myService.serviceProperty = 'someWhateverValue';
console.log('and after', this.myService.serviceProperty); *//logs null*
}
}
...
}
Now in the test I would like to check that the property has the value of someWhateverValue. Or that the setter was called, or that the setter was called with someWhateverValue, but I ran out of ideas, even of what else to google...So this is my test:
...
describe(...()=>{
let mockMyService: any;
beforeEach(()=>{
mockMyService = jasmine.createSpyObj('MyService', ['aFunction', 'anotherFumction'], {serviceProperty: null});
TestBed.configureTestingModule({
...
providers: [..., {provide: MyService, useValue: mockMyService}]
});
fixture = TestBed.createComponent(MainComponent);
})
//ONE VERSION
it('should check some stuff', ()=>{
fixture.detectChanges();
expect(mockMyService.myProperty).toEqual('someWhateverValue'); *//this one says that null doesn't equal 'someWhateverValue'*
});
//ANOTHER VERSION
it('should check some stuff', ()=>{
*//the next line, if I don't remove the property from the spy, it throws the error:
//Error: <spyOnProperty> : myProperty#get has already been spied upon;
//however, if I remove it, I get Error: <spyOnProperty> : myProperty property does not exist*
const getter = spyOnProperty(mockMyService, 'myProperty', 'get').and.returnValue(null);
*//if I remove the above line and leave the property in the spy declaration, I get
//Error: <spyOnProperty> : myProperty#set has already been spied upon, and this,
//#set has already been spied upon, doesn't even exist on google...*
const setter = spyOnProperty(mockMyService, 'myProperty', 'set');
fixture.detectChanges();
expect(setter).toHaveBeenCalled();
});
}
...
So how can I check that the value of this property has been changed?
LATER EDIT
I created a more simple scenario:
service:
...
export class MyService {
private _someObj;
get someObj() {
return this._someObj;
}
set someObj(val) {
this._someObj = val;
}
}
component:
someFunction() {
console.log('before', this.myService.someObj ); *//logs null*
this.myService.someObj = { prop1: 'val1', prop2: 'val2' };
console.log('and after', this.myService.someObj ); *//logs null*
}
test:
fit('should create the object', () => {
(Object.getOwnPropertyDescriptor(mockMyService, 'someObj')?.get as jasmine.Spy<() => any>).and.returnValue(null);
component.someFunction();
expect(mockMyService['someObj']).toEqual({ prop1: 'val1', prop2: 'val2' });
*//I get null to equal...*
});
if instead of making it null, I make it {prop1: '', prop2: ''} and in the controller function I go this.myService.someObj.prop1 = 'val1', it gets set to the correct value. But I need it to be null from the beginning so that I can test the scenario where it gets set; If I set it to null, as in the test above, no matter what I do with it, it stays null at the second log in the component.