1

I have this logic when starting NodeJS app:

  const twiddleService = new twiddleService(
    new twiddleClient(),
    new UserRepository(),
    new BusinessRepository()
  );
  const twiddleController = new twiddleController(twiddleService);

I've unit tested twiddleService by mocking twiddleClient.

Now I want to unit test twiddleController and mock twiddleService.

In my twiddleController.test.ts file I have

import { twiddleService } from '../../src/services/twiddle-service';
jest.mock('../../src/services/twiddle-service');
const twiddleController = new twiddleController(new twiddleService());

Obviously this doesn't work because twiddleService expects 3 arguments. I could mock twiddleClient and the repositories again, but ideally I wouldn't.

Basically the goal is I want to be able to do something like

jest.spyOn(TwiddleService, 'createBananas').mockResolvedValue('b');

So that I can unit test my controller.

What are best practices when it comes to solving this problem?

[Also I'm using typescript]

Asool
  • 13,031
  • 7
  • 35
  • 49

1 Answers1

1

I don't think you need to import and call jest.mock on the twiddle-service at all.

Since you are using Dependency Injection to provide the twiddleService instance to the twiddleController constructor, your test can supply a simple object - conforming to the Twiddle Service's interface, of course - to the new twiddleController() call. You can use jest.fn with an implementation argument to define what gets returned by the service's createBananas method to the twiddleController instance. The resulting test would look something like the following:

describe("TwiddleController", () => {
  test("calls createBananas method of twiddleService instance", () => {
    const mockTwiddleService = {
      createBananas: jest.fn(() => "b"),
    };

    const twiddleController = new TwiddleController(mockTwiddleService);

    expect(twiddleController.doSomethingWithBananas()).toBe("b");
  });
});

76484
  • 8,498
  • 3
  • 19
  • 30