Article image
CARLOS
CARLOS09/10/2023 21:09
Compartilhe

TESTES AUTOMATIZADOS

    "artigo de Felipe Nascimento"

    Mocks e Stubs em testes: o que são e quais as diferenças

    image

    imageFelipe Nascimento

    17/03/2021

    Compartilhe





    Nesse artigo vamos falar sobre mocks e stubs, o que são e quais as suas diferenças.

    Para entender esses conceitos, primeiro é importante saber o que são os chamados dublês de teste. Gerard Meszaros, o autor do livro XUnit Test Patterns: Refactoring Test Code usa o termo dublê de teste para qualquer tipo de objeto falso usado no lugar de um objeto real para fins de teste.

    Podemos dizer que um dublê nos ajuda testar nosso código eliminando dependências, como por exemplo evitar de fazer uma conexão com banco de dados para testar uma funcionalidade. No livro também ele define os dublês em alguns tipos, nesse artigo vamos focar em mocks e stubs.

    Mocks

    Ao escrever testes, às vezes precisamos simular partes de nosso sistema para tornar os testes possíveis e os resultados reproduzíveis. Mocks são imitações ou unidades falsas que simulam o comportamento de unidades reais. Por exemplo, temos a seguinte função pagamento() que é responsável por fazer pagamento e dentro dela existe uma outra função que faz conexão com banco de dados, conexão essa que faz parte do processo de pagamento. Essas funções estão dentro de uma classe maior que tem relação com pagamentos:

    const pagamento = (descontos, salarioBruto) => { 
     conectaComBanco()
    
    //...código omitido
    
    } 
    

    Para testar a função pagamento() não necessariamente precisamos ter a função conectaComBanco() como dependência, temos que conseguir testar a função pagamento() independente do que acontece dentro da função conectaComBanco().

    O que podemos fazer nessa situação é mockar ou criar um mock, simulando assim o comportamento da função conectaComBanco() sem precisar executar de fato a função. Para isso vamos escrever um teste que será feito com a biblioteca sinonjs:

    //...código omitido
    
    it(“mock the conectaComBanco function”, function(){
     mock = sinon.mock(ObjetoDeTeste)
     expectation = mock.expects(‘conectaComBanco’)
     expectation.exactly(1)
     ObjetoDeTeste.pagamento(100, 1000)
     mock.verify()
    })
    

    O que fizemos nesse teste foi:

    Dentro do it descrevemos o teste, depois criamos um mock da classe de pagamento e em seguida dizemos que esse mock espera uma função mock.expects(‘conectaComBanco’). Na variável expectation esperamos que ela seja chamada apenas uma vez. Depois executamos a função pagamento()e verificamos se o teste passou.

    Ou seja, com o mock feito, eliminamos dependências complexas que conectaComBanco() precisa executar. Agora que vimos como funciona um mock, vamos para um cenário em que utilizaremos um stub para testar uma unidade.

    Stubs

    Os stubs são parecidos com os mocks, mas geralmente são mais simples. Considere a seguinte função de pagamento que recebe uma função chamada salarioFinal() para fazer um cálculo e retornar um salário:

    const pagamento = (descontos, salarioBruto) => { 
    //...código omitido
     salario = salarioFinal(descontos, salarioBruto)
    return salario
    } 
    

    Vamos utilizar a biblioteca sinonjs para escrever esse stub:

    //...código omitido
    
    it(“stub the aumento function”, function(){
     stub = sinon.stub(ObjetoDeTeste, salarioFinal)
     stub.withArgs(100, 1000).returns(900)
     expect( ObjetoDeTeste.pagamento(10, 1000)).to.be.equal(900)
    })
    

    O que fizemos nesse stub foi:

    Dentro do it descrevemos o teste, depois criamos um stub da classe de pagamento, passando a função salarioFinal() que retorna um resultado. Em seguida passamos para esse stub os valores que a função salarioFinal() vai receber e o quanto ela deve retornar, por fim testamos a função pagamento, dela é esperado que retorne 900.

    O que podemos perceber é que o stub implementa apenas o mínimo para permitir que o código em teste funcione, ou seja, o stub possui um comportamento previsível de retorno, baseado nos parâmetros passados para teste.

    Diferenças

    Usamos o mock quando queremos saber se uma função vai ser chamada corretamente, quantas vezes ela vai ser chamada, se os parâmetros esperados são os corretos, já o stub vai nos dizer se o resultado do código retorna de acordo com os parâmetros passado, se retorna sucesso, erro ou exceção por exemplo, é previsível.

    Compartilhe
    Comentários (0)