I have an Angular component I am writing tests for. The SUT component has a function I need to spy on (not ideal as noted further below). I want to set up the TestBed so that the function already has a spy assigned when TestBed creates the component.
I know how to spy on the function once the SUT component has been created. But I suspect there is a way to do that declaratively, I just can't find it. One reason I need that for is that if the SUT component executes some functions right after the component is created (e.g. from the constructor), I need the spies on those functions to be in place before the SUT is created.
I also realize that SUT shouldn't normally have its elements mocked/spied, and I actually ended up rewriting my tests accordingly. But I am still curious whether the "SUT declarative spying" is possible.
I tried to achieve this with TestBed.configureTestingModule.overrideComponent but that doesn't provide access to individual component functions to override.
I also tried ng-mocks, hoping MockBuilder might have support for mocking one specific function of the SUT component, but no luck there either.
The only way you can spy a method of SUT is to update its prototype before the creation of an instance of it:
let backup: any;
beforeEach(() => {
backup = TargetComponent.prototype.func;
TargetComponent.prototype.func = jasmine.createSpy().and.returnValue('mock');
});
afterEach(() => {
TargetComponent.prototype.func = backup;
});
An example is here: https://codesandbox.io/s/objective-scott-euy6dz?file=/src/test.spec.ts