When mocking dependencies in my Angular tests, I usually create a spy object using jasmine.createSpyObj
:
const serviceSpy= jasmine.createSpyObj('MyService', ['method']);
then provide it to the TestBed:
providers: [
{provide: MyService, useValue: serviceSpy}
]
When I use it in my test, I can then specify the desired return value:
serviceSpy.method.and.returnValue(of([...]));
Now I also need to mock properties and I cannot find out how it should be done. createSpyObj
does allow the definition of property names:
const serviceSpy= jasmine.createSpyObj('MyService', ['method'], ['property']);
but I've tried varies solutions based on the numerous articles and answers out there without any success, e.g.:
// Cannot read property 'and' of undefined
serviceSpy.property.and.returnValue(true);
// not declared configurable
spyOnProperty(serviceSpy, 'property').and.returnValue(true);
// no build errors, but value stays 'undefined'
serviceSpy.property = true;
The only way I could make it 'half' work is:
let fakeValue = true;
const serviceSpy= jasmine.createSpyObj('MyService', ['method'], {'property': fakeValue});
The problem here is that it's a one-time set at creation. If I want to change the expected value in the test, it does not work.
fakeValue = false;
serviceSpy.property ==> stays to the initial value 'true';
Does there exist a solution to both mock methods and properties by creating a spy object, or should I create my own fake class on which I can then use spyOn
and spyOnProperty
?
I would also like to know what the usage is of the properties array in the createSpyObj
definition. So far I have not seen any example on the web that explains it.
See Question&Answers more detail:
os