En este tema, aprenderemos sobre dos técnicas fundamentales en las pruebas de software: Mocking y Stubbing. Estas técnicas son esenciales para aislar el código que estamos probando y simular comportamientos de dependencias externas.
¿Qué es Mocking?
Mocking es una técnica utilizada en las pruebas unitarias para simular el comportamiento de objetos reales. Los mocks permiten verificar que ciertas interacciones ocurren entre los objetos, como llamadas a métodos con parámetros específicos.
Ventajas del Mocking
- Aislamiento: Permite probar una unidad de código sin depender de otras partes del sistema.
- Control: Facilita la simulación de diferentes escenarios y comportamientos.
- Velocidad: Las pruebas son más rápidas porque no dependen de recursos externos como bases de datos o servicios web.
Ejemplo de Mocking en Ruby con RSpec
# Ejemplo de clase que queremos probar
class Car
def initialize(engine)
@engine = engine
end
def start
@engine.start
end
end
# Prueba con Mocking
RSpec.describe Car do
it 'starts the engine' do
engine = double('Engine')
expect(engine).to receive(:start)
car = Car.new(engine)
car.start
end
endEn este ejemplo:
- Creamos un mock para la clase
Engineusandodouble('Engine'). - Configuramos una expectativa para que el método
startsea llamado en el mock. - Verificamos que la llamada al método
startocurre cuando se llama al métodostartdel objetoCar.
¿Qué es Stubbing?
Stubbing es una técnica utilizada para reemplazar el comportamiento de métodos o funciones con implementaciones predefinidas. Los stubs permiten simular respuestas de métodos sin ejecutar el código real.
Ventajas del Stubbing
- Simulación: Permite simular respuestas de métodos sin ejecutar el código real.
- Flexibilidad: Facilita la creación de diferentes escenarios de prueba.
- Independencia: Las pruebas no dependen de la implementación real de los métodos.
Ejemplo de Stubbing en Ruby con RSpec
# Ejemplo de clase que queremos probar
class WeatherService
def fetch_weather
# Lógica para obtener el clima desde un servicio externo
end
end
class WeatherReporter
def initialize(service)
@service = service
end
def report
@service.fetch_weather
end
end
# Prueba con Stubbing
RSpec.describe WeatherReporter do
it 'reports the weather' do
service = double('WeatherService')
allow(service).to receive(:fetch_weather).and_return('Sunny')
reporter = WeatherReporter.new(service)
expect(reporter.report).to eq('Sunny')
end
endEn este ejemplo:
- Creamos un stub para la clase
WeatherServiceusandodouble('WeatherService'). - Configuramos el stub para que el método
fetch_weatherdevuelva'Sunny'. - Verificamos que el método
reportdel objetoWeatherReporterdevuelve'Sunny'.
Ejercicio Práctico
Ejercicio 1: Mocking
Crea una clase BankAccount con un método deposit(amount) que llama a un método notify(amount) de un objeto Notifier. Escribe una prueba que verifique que el método notify es llamado con el monto correcto.
# Clase BankAccount
class BankAccount
def initialize(notifier)
@notifier = notifier
end
def deposit(amount)
@notifier.notify(amount)
end
end
# Prueba con Mocking
RSpec.describe BankAccount do
it 'notifies the deposit amount' do
notifier = double('Notifier')
expect(notifier).to receive(:notify).with(100)
account = BankAccount.new(notifier)
account.deposit(100)
end
endEjercicio 2: Stubbing
Crea una clase CurrencyConverter con un método convert(amount, from_currency, to_currency) que llama a un método get_exchange_rate(from_currency, to_currency) de un objeto ExchangeRateService. Escribe una prueba que simule diferentes tasas de cambio usando stubs.
# Clase CurrencyConverter
class CurrencyConverter
def initialize(service)
@service = service
end
def convert(amount, from_currency, to_currency)
rate = @service.get_exchange_rate(from_currency, to_currency)
amount * rate
end
end
# Prueba con Stubbing
RSpec.describe CurrencyConverter do
it 'converts currency using the exchange rate' do
service = double('ExchangeRateService')
allow(service).to receive(:get_exchange_rate).with('USD', 'EUR').and_return(0.85)
converter = CurrencyConverter.new(service)
expect(converter.convert(100, 'USD', 'EUR')).to eq(85)
end
endConclusión
En esta sección, hemos aprendido sobre las técnicas de Mocking y Stubbing en Ruby, utilizando RSpec. Estas técnicas son esenciales para escribir pruebas unitarias efectivas, permitiendo aislar el código bajo prueba y simular comportamientos de dependencias externas. Con la práctica, dominarás estas técnicas y podrás escribir pruebas más robustas y confiables.
En el siguiente módulo, profundizaremos en las mejores prácticas de estilo de código y convenciones en Ruby. ¡Sigue adelante!
Curso de Programación en Ruby
Módulo 1: Introducción a Ruby
Módulo 2: Conceptos Básicos de Ruby
Módulo 3: Trabajando con Colecciones
Módulo 4: Programación Orientada a Objetos en Ruby
- Clases y Objetos
- Variables y Métodos de Instancia
- Variables y Métodos de Clase
- Herencia
- Módulos y Mixins
Módulo 5: Conceptos Avanzados de Ruby
- Bloques, Procs y Lambdas
- Metaprogramación
- Manejo de Excepciones
- Entrada/Salida de Archivos
- Expresiones Regulares
Módulo 6: Introducción a Ruby on Rails
- ¿Qué es Ruby on Rails?
- Configuración del Entorno Rails
- Creando una Aplicación Simple en Rails
- Arquitectura MVC
- Enrutamiento
Módulo 7: Pruebas en Ruby
- Introducción a las Pruebas
- Pruebas Unitarias con Minitest
- Desarrollo Guiado por Comportamiento con RSpec
- Mocking y Stubbing
Módulo 8: Mejores Prácticas en Ruby
- Estilo de Código y Convenciones
- Refactorización
- Optimización del Rendimiento
- Mejores Prácticas de Seguridad
