Node

Jest private method mocking

5linesys 2024. 12. 11. 21:38

Object.getPrototypeOf()

Object.getPrototypeOf() 를 사용하면 인스턴스의 원형에 접근할 수 있어 private 메서드도 mocking 할 수 있다.

class MyClass {
  private myPrivateMethod(): string {
    return 'Original Private Method';
  }

  public callPrivateMethod(): string {
    return this.myPrivateMethod();
  }
}

describe('MyClass', () => {
  it('should mock private method using `Object.getPrototypeOf`', () => {
    const myInstance = new MyClass();
    const prototype = Object.getPrototypeOf(myInstance);

    const spy = jest.spyOn(prototype as any, 'myPrivateMethod').mockReturnValue('Mocked Private Method');

    const result = myInstance.callPrivateMethod();

    expect(spy).toHaveBeenCalled();
    expect(result).toBe('Mocked Private Method');
  });
});

 

  • 장점: 타입 시스템을 유지하며, 프로토타입 체인을 이용해 안정적으로 접근할 수 있다.
  • 단점: 약간의 복잡함이 있다.

DI

nestjs 의 경우 class 가 모듈화 되어있어 DI 를 활용하여 해결할 수 있다.

import { Injectable } from '@nestjs/common';

@Injectable()
class HelperService {
  myHelperMethod(): string {
    return 'Original Helper Method';
  }
}

@Injectable()
class MyService {
  constructor(private readonly helperService: HelperService) {}

  public callPrivateMethod(): string {
    return this.helperService.myHelperMethod();
  }
}
import { Test, TestingModule } from '@nestjs/testing';
import { MyService } from './my-service';
import { HelperService } from './helper-service';

describe('MyService', () => {
  let myService: MyService;
  let helperService: HelperService;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [MyService, HelperService],
    }).compile();

    myService = module.get<MyService>(MyService);
    helperService = module.get<HelperService>(HelperService);
  });

  it('should call myHelperMethod and return the mocked result', () => {
    // 모킹 (mocking) 처리
    jest.spyOn(helperService, 'myHelperMethod').mockReturnValue('Mocked Helper Method');

    const result = myService.callPrivateMethod();

    expect(helperService.myHelperMethod).toHaveBeenCalled();
    expect(result).toBe('Mocked Helper Method');
  });
});
  • 설명
    • HelperService 는 MysSevercie 의 private 메서드에 해당한다.
    • DI 로 주입한 HelperSevice 는 독립된 서비스이므로, 재사용이 가능하고 직접 모킹이 가능하다.
  • 장점: 타입 시스템을 깨뜨리지 않으며 유지보수가 쉽다.
  • 단점: 의존성을 추가해야 하므로 구조에 따라 코드 리펙터링이 필요하다.