Javascript é lindo, talvez a única linguagem em que você pode pegar uma função e reescrever ela para um proposito totalmente diferente do que ela foi inventada.

Basta usar um prototype e pronto, você consegue fazer um alert enviar requisições para um servidor. Essa função as vezes é muito útil quando você precisa criar testes unitários, afinal basta isolar as dependências em alguns casos até sobreescrever totalmente, como é no caso do stub no Sinon e Spy do Jest.

Péssima prática que toma tempo da execução dos testes e acopla nas dependências do que está sendo testado, infelizmente o Jest só funciona dessa forma e não tem mais como salvar (talvez tenha, mas eu não vou gastar meu tempo resolvendo merda deles).

Porém com sinon, nem tudo está perdido. Basta fugir um pouco da documentação. Recentemente criando alguns testes unitários, tive uns problemas por sobreescrever uma função externa de mascara de documentos. O sinon quebrou o mocha e nada dos testes rodar. Eu sabia que o problema era isso e tentei o restore() após execução dos testes, mas sem sucesso.

As funções tinha sua utilidade nos testes, ainda mais por que ajudaria os testes terem o output dessa dependência como comparação, ao invés de um undefined. Foi aqui que eu percebi que poderia ter o melhor dos dois mundos.


Vamos a solução usando callsFake. Para começar vamos imaginar que vamos testar a seguinte função que devolve uma stringformatada.

// mask-string.js

export const MaskString = ({MaskDocuments}) =>
	(str) => MaskPhone(str);

Sim, no arquivo de teste você declara seu stub normal.


import {MaskString} from './mask-string.js'
import {MaskPhone} * from './MaskPhone';

describe('example', () => {
    let result;
    const maskDocuments = sinon.stub();
    const strCtrl = '11977444000';
    
    beforeEach(() => {
        maskDocuments.callsFake(arg => MaskPhone(arg));

        result = MaskString({
            maskDocuments
        })(strCtrl);
    });
    
    it('external', () => {
        expect(maskDocuments.called).to.be.true
    });
    
    it('expect result be formatted', () =>
       expect(result).to.be.equal(MaskPhone(strCtrl))
    });
});

Com o código acima, vc não precisa escrever toda a simulação da dependencia, pode trocar no futuro se for necessário.

DISCLAIMER: SÓ faça isso dependências que você sabe que funções simples e com retornos claros e de preferência com dependências já escrita no seu sistema