1

I recently got an enterprise project to write unit tests for. The app is really huge. It has a large injection three. When I'm setting up the tests, it took me half day to mock only the injected services. The problem is, that the service I'm testing, has n number of injected services, where every injected service has again n number of injected services and the list goes on an on to an infinite number. Currently I'm mocking them just by creating fake classes, but then again, writing fake methods for every fake class is a huge time consuming task in this project. (mainly because every injected service has a large number of subscriptions in constructors).

My current testing set-up:

class FrameStateServiceStub {
    public changedCurrentFrame: Observable<LayerId> = EMPTY;
    public changedAvailableFrames: Observable<LayerId> = of("");

    public getCurrentFrame(layerId: LayerId): Frame {
        return frame;
    }

    public getAvailableFrames(layerId: LayerId): Frame[] {
        return [frame];
    }
}

class LoadingIndicatorServiceStub {
}

describe("DisplayService", () => {

  const frameStateServiceStub = new FrameStateServiceStub();
  const loadingIndicatorServiceStub = new LoadingIndicatorServiceStub();

  beforeEach(() => {
    TestBed.configureTestingModule({
        providers: [
            DisplayService,
            {provide: FrameStateService, useValue: frameStateServiceStub},
            {provide: LoadingIndicatorService, useValue: loadingIndicatorServiceStub},
            ...
        ]
    });
  });
});

I'm wondering if there is an easier (less time consuming) way of doing this?

Runtime Terror
  • 6,242
  • 11
  • 50
  • 90

1 Answers1

0

Here are best practices you can follow:

  1. Have a list of mock test classes under a folder called mocksTests. Do not create a class in every spec file.
  2. Instead of instantiating class in every spec file, you can directly add them in providers array and refer to them in useClass instead of useValue.
  3. You don't have to bother about 'n number of injected services, where every injected service has again n number of injected services'. You can just concentrate on adding the services used in your component/service's constructor.
import { MockFrameStateService } from '../some/path1';
import { MockLoadingIndicatorService } from '../some/path2';

...

describe("DisplayService", () => {
   beforeEach(() => {
      TestBed.configureTestingModule({
        providers: [
            DisplayService,
            {provide: FrameStateService, useClass: MockFrameStateService },
            {provide: LoadingIndicatorService, useClass: MockLoadingIndicatorService},
            ...
        ]
    });
  });
});