Pesquisa de site

Como testar métodos privados em Typescript


Quando tentei fazer test de unidade para métodos privados em uma Classe, obtive o erro métodos privados só são acessíveis dentro da classe. Aqui adicionei um trecho de exemplo da minha classe e do teste mocha. Por favor, me forneça uma solução para implementar teste de unidade para métodos privados.

Nome da Classe: Notification.ts

class Notification {
 constructor() {}
 public validateTempalte() {
  return true;
 }

 private replacePlaceholder() {
  return true;
 }
}

Teste de Unidade:

import {Notification} from 'Notification';
import * as chai from "chai";

describe("Notification", function(){

  describe('#validateTempalte - Validate template', function() {
      it('it should return success', function() {
        const result = new Notification()
        chai.expect(result.validateTempalte()).to.be.equal(true);
      });
    });
  describe('#replacePlaceholder - Replace Placeholder', function() {
      it('it should return success', function() {
        const result = new Notification()
        // As expected getting error "Private is only accessible within class"
        chai.expect(result.replacePlaceholder()).to.be.equal(true);
      });
    });
});

Como uma solução alternativa, atualmente, estou mudando o especificador de acesso da função replacePlaceholder para público. Mas eu não acho que seja uma abordagem válida.

Resposta #1

Uma possível solução para omitir as verificações do Typescript é acessar a propriedade dinamicamente (Não dizendo se é bom).

myClass['privateProp'] ou para métodos: myClass['privateMethod']()

Resposta #2

Tecnicamente, nas versões atuais do TypeScript, métodos privados são verificados como privados apenas em tempo de compilação - então você pode chamá-los.

class Example {
    public publicMethod() {
        return 'public';
    }

    private privateMethod() {
        return 'private';
    }
}

const example = new Example();

console.log(example.publicMethod()); // 'public'
console.log(example.privateMethod()); // 'private'

Menciono isso apenas porque você perguntou como fazer, e é assim que você poderia fazer.

Resposta Correta

No entanto, esse método privado deve ser chamado por algum outro método... caso contrário, ele não será chamado de forma alguma. Se você testar o comportamento desse outro método, você cobrirá o método privado no contexto em que ele é usado.

Se você testar especificamente métodos privados, seus testes se tornarão fortemente acoplados aos detalhes de implementação (ou seja, um bom teste não precisaria ser alterado se você refatorasse a implementação).

Isenção de responsabilidade

Se você ainda testá-lo no nível de método privado, o compilador poderá no futuro mudar e fazer o teste falhar (ou seja, se o compilador tornasse o método "realmente" privado, ou se uma versão futura do ECMAScript adicionasse palavras-chave de visibilidade, etc).

Resposta #3

No meu caso, eu uso o protótipo do objeto para acessar um método privado. Funciona bem e o TS não reclama.

Por exemplo:

class Example {
    private privateMethod() {}
}

describe() {
    it('test', () => {
        const example = new Example();
        const exampleProto = Object.getPrototypeOf(example);

        exampleProto.privateMethod();
    })
}

Se você usar um método estático, então use exampleProto.constructor.privateMethod();.

Artigos relacionados