I've been working with Angular for a while. In Angular components, the constructor is often kept blank and any sort of initialization methods are moved into ngOnInit(). If I have to spy on any method calls made from inside the component, I can do so after instantiating the component.

I recently was writing tests against a class with method calls inside the constructor, and drew a blank on how to spy on that method.

Imagine this code:

view plain print about
1export class MyClass() {
2 constructor() {
3 otherMethod();
4 };
5 otherMethod() {
6 // do something
7 }
8}

A traditional test I've been writing would do something like this:

view plain print about
1const myClass = new MyClass();
2spyOn(myClass, 'otherMethod');
3expect(myClass.otherMethod).toHaveBeenCalled();

But, this test failed. otherMethod() was called before I can create the spy. We can't attempt the spy before instantiating the class.

I was confounded, both that I had not run into this before, and because I didn't know what the solution was.

Off to the Internet to find a solution. If we put a spy on the classes' prototype, then we can add the spy before the class gets instantiated.

view plain print about
1spyOn(MyClass.prototype, 'otherMethod');
2const myClass = new MyClass();
3expect(myClass.otherMethod).toHaveBeenCalled();

Notice that we're spying on the class name, not an instance of the class. This approach will work. Although, every other instance you create of the class in other tests have the spy on 'otherMethod()'.