Как протестировать приватную функцию?

В TypeScript, приватные функции доступны только внутри класса, в котором они определены. Из-за этого, напрямую доступиться к приватным функциям извне класса невозможно. Однако, есть несколько подходов, которые позволяют тестировать приватные функции.

1. Использование экспорта для тестирования:
В разработке приложений часто используется практика прототипирования или временного изменения видимости приватных методов, чтобы их можно было вызывать и тестировать извне класса. В TypeScript нам это может помочь. Например, если у нас есть класс MyClass:

   class MyClass {
       private privateFunc(): void {
           // ...
       }
   }

Мы можем временно изменить уровень доступа на protected и добавить публичный метод, который будет выступать в качестве оболочки для приватного метода:

   class MyClass {
       private privateFunc(): void {
           // ...
       }

       public publicFunc(): void {
           this.privateFunc();
       }
   }

Теперь мы можем создать экземпляр класса MyClass и вызвать publicFunc() для тестирования приватной функции privateFunc():

   const myClass = new MyClass();
   myClass.publicFunc(); // вызов приватной функции извне

2. Использование отражений (Reflection) TypeScript:
Другой способ протестировать приватные функции в TypeScript - это использовать отражения (Reflection). Во время выполнения TypeScript (JavaScript) поддерживает возможность получения доступа к приватным методам и свойствам объекта через использование отражений. Вот пример кода:

   class MyClass {
       private privateFunc(): void {
           // ...
       }
   }
   
   const myClass = new MyClass();
   const privateMethod = myClass['privateFunc'] as () => void; // получение доступа к приватному методу
   privateMethod(); // вызов приватного метода

Однако, следует помнить, что использование отражений является сомнительным решением с точки зрения безопасности и может нарушать инкапсуляцию класса, поэтому не рекомендуется использовать этот подход в продакшн-коде.

3. Тестирование через публичные методы:
Когда приватная функция не имеет побочных эффектов, иногда проще протестировать ее через публичный метод, который использует эту приватную функцию в своей реализации. Например:

   class MyClass {
       private privateFunc(): number {
           return 42;
       }

       public publicFunc(): number {
           return this.privateFunc() * 2;
       }
   }

Теперь мы можем создать экземпляр класса MyClass и протестировать его публичный метод publicFunc(), который включает вызов приватной функции privateFunc():

   const myClass = new MyClass();
   const result = myClass.publicFunc(); // результат 84

В этом случае мы проверяем результат публичного метода publicFunc(), который зависит от приватной функции privateFunc(), что в свою очередь позволяет нам проверять поведение приватной функции, не обращаясь к ней непосредственно.

Несмотря на эти методы, следует помнить, что приватные методы исключены из публичного API класса сознательно, чтобы обеспечить инкапсуляцию и отделение внутренней логики класса от внешнего использования. Поэтому, при тестировании приватной функции, стоит сконцентрироваться на тестировании публичных интерфейсов класса, поскольку они являются гарантированными контрактами для пользователей класса.