En aquest tema, aprendrem sobre dues tècniques essencials en les proves de programari: el mocking i el stubbing. Aquestes tècniques ens permeten simular el comportament de certs components del sistema per aïllar i provar altres parts del codi de manera més efectiva.

Què és el Mocking?

El mocking és una tècnica en la qual es crea un objecte simulat (mock) que imita el comportament d'un objecte real. Els mocks s'utilitzen per verificar que certes interaccions amb altres objectes es produeixen com s'espera.

Exemple de Mocking amb RSpec

# Instal·la RSpec si no ho has fet ja
# gem install rspec

# Crea un fitxer anomenat `mocking_example_spec.rb`
require 'rspec'

class Salutador
  def initialize(servei)
    @servei = servei
  end

  def saluda
    @servei.envia_missatge("Hola!")
  end
end

RSpec.describe Salutador do
  it 'envia un missatge de salutació' do
    servei_mock = double("Servei")
    expect(servei_mock).to receive(:envia_missatge).with("Hola!")

    salutador = Salutador.new(servei_mock)
    salutador.saluda
  end
end

# Executa les proves amb el comandament:
# rspec mocking_example_spec.rb

Explicació del Codi

  1. Creació del Mock: servei_mock = double("Servei") crea un objecte simulat.
  2. Expectativa: expect(servei_mock).to receive(:envia_missatge).with("Hola!") defineix que esperem que el mètode envia_missatge sigui cridat amb l'argument "Hola!".
  3. Prova: salutador.saluda crida el mètode saluda, que al seu torn crida envia_missatge en el mock.

Què és el Stubbing?

El stubbing és una tècnica en la qual es defineix el comportament d'un mètode en un objecte simulat. Els stubs s'utilitzen per proporcionar respostes predefinides a les crides de mètodes.

Exemple de Stubbing amb RSpec

# Crea un fitxer anomenat `stubbing_example_spec.rb`
require 'rspec'

class Calculadora
  def initialize(api)
    @api = api
  end

  def suma(a, b)
    @api.obte_suma(a, b)
  end
end

RSpec.describe Calculadora do
  it 'retorna la suma de dos nombres' do
    api_stub = double("API")
    allow(api_stub).to receive(:obte_suma).with(2, 3).and_return(5)

    calculadora = Calculadora.new(api_stub)
    resultat = calculadora.suma(2, 3)

    expect(resultat).to eq(5)
  end
end

# Executa les proves amb el comandament:
# rspec stubbing_example_spec.rb

Explicació del Codi

  1. Creació del Stub: api_stub = double("API") crea un objecte simulat.
  2. Definició del Comportament: allow(api_stub).to receive(:obte_suma).with(2, 3).and_return(5) defineix que quan el mètode obte_suma és cridat amb els arguments 2 i 3, ha de retornar 5.
  3. Prova: resultat = calculadora.suma(2, 3) crida el mètode suma, que al seu torn crida obte_suma en el stub.

Exercicis Pràctics

Exercici 1: Mocking

Crea una classe Notificador que tingui un mètode notifica que cridi un mètode envia_notificacio en un servei extern. Escriu una prova que utilitzi un mock per verificar que envia_notificacio és cridat amb el missatge "Notificació enviada".

Solució

class Notificador
  def initialize(servei)
    @servei = servei
  end

  def notifica
    @servei.envia_notificacio("Notificació enviada")
  end
end

RSpec.describe Notificador do
  it 'envia una notificació' do
    servei_mock = double("Servei")
    expect(servei_mock).to receive(:envia_notificacio).with("Notificació enviada")

    notificador = Notificador.new(servei_mock)
    notificador.notifica
  end
end

Exercici 2: Stubbing

Crea una classe Conversor que tingui un mètode converteix que cridi un mètode obte_taxa en un servei extern per obtenir la taxa de conversió entre dues monedes. Escriu una prova que utilitzi un stub per definir que obte_taxa retorna 1.2 quan es crida amb els arguments "USD" i "EUR".

Solució

class Conversor
  def initialize(servei)
    @servei = servei
  end

  def converteix(amount, from_currency, to_currency)
    taxa = @servei.obte_taxa(from_currency, to_currency)
    amount * taxa
  end
end

RSpec.describe Conversor do
  it 'converteix una quantitat de USD a EUR' do
    servei_stub = double("Servei")
    allow(servei_stub).to receive(:obte_taxa).with("USD", "EUR").and_return(1.2)

    conversor = Conversor.new(servei_stub)
    resultat = conversor.converteix(100, "USD", "EUR")

    expect(resultat).to eq(120)
  end
end

Errors Comuns i Consells

  1. No definir expectatives clares: Assegura't de definir clarament què esperes que faci el mock o el stub.
  2. No aïllar correctament les proves: Utilitza mocks i stubs per aïllar les proves i evitar dependències externes.
  3. Oblidar-se de verificar les interaccions: En el cas dels mocks, verifica que les interaccions esperades es produeixen.

Conclusió

El mocking i el stubbing són tècniques poderoses per a les proves de programari que permeten simular el comportament d'objectes i definir respostes predefinides. Aquestes tècniques ajuden a aïllar el codi que s'està provant i a assegurar-se que les interaccions amb altres components es produeixen com s'espera. Practica aquestes tècniques amb els exercicis proporcionats per millorar les teves habilitats en proves de programari.

© Copyright 2024. Tots els drets reservats