Skip to content
StackPractices
beginner Por Mathias Paulenko

Escribir Unit Tests con Mocks y Stubs

Cómo aislar código bajo test usando objetos mock, stubs y spies para reemplazar dependencias externas como bases de datos, APIs y sistemas de archivos.

Temas: testing

Nota para desarrolladores hispanohablantes: Esta guía incluye ejemplos y convenciones de nomenclatura adaptadas a equipos que trabajan en español. Cuando existen diferencias significativas en terminología técnica entre el inglés y el español, se indican explícitamente para facilitar la comunicación en equipos multiculturales.

Visión general

Los unit tests verifican que una sola función o clase se comporta correctamente en aislamiento. Pero la mayoría del código depende de sistemas externos — bases de datos, APIs HTTP, sistemas de archivos — que son lentos, poco confiables o no disponibles durante los tests. El mocking reemplaza estas dependencias con sustitutos controlados que devuelven respuestas predeterminadas, lanzan excepciones bajo demanda, o registran cómo fueron llamados.

Un test bien aislado corre en milisegundos, produce el mismo resultado cada vez, y falla solo cuando el código bajo test — no sus dependencias — está roto. A continuacion se cubre los tres test doubles esenciales: stubs (datos falsos), mocks (verificación de comportamiento), y spies (registro de llamadas).

Cuándo usarlo

Usa esta receta cuando:

  • Escribiendo unit tests para código que llama bases de datos, APIs o servicios de terceros. Consulta Integration Testing para testear con dependencias reales.
  • Testeando manejo de errores para escenarios difíciles de disparar en sistemas reales. Consulta API Contract Testing para verificar respuestas de error de API.
  • Acelerando un suite de tests lento dominado por tests de estilo integración
  • Verificando que una función llama a un colaborador con los argumentos correctos
  • Reemplazando dependencias no determinísticas (generadores random, hora actual, UUIDs). Consulta Call REST API para testear lógica de clientes HTTP.

Solución

Jest Mock (JavaScript)

import { processPayment } from './payment';
import { sendEmail } from './email';

jest.mock('./email');

test('sends receipt email after successful payment', async () => {
  sendEmail.mockResolvedValue({ messageId: '123' });
  await processPayment({ amount: 100, userId: 'u1' });
  expect(sendEmail).toHaveBeenCalledWith(
    expect.objectContaining({
      to: 'user@example.com',
      subject: 'Payment received',
    })
  );
});

test('handles email service failure gracefully', async () => {
  sendEmail.mockRejectedValue(new Error('SMTP down'));
  const result = await processPayment({ amount: 100, userId: 'u1' });
  expect(result.emailSent).toBe(false);
  expect(result.paymentId).toBeDefined();
});

Pytest Mock (Python)

from unittest.mock import patch, MagicMock
from payment import process_payment

def test_payment_success():
    with patch('payment.send_email') as mock_email:
        mock_email.return_value = {'message_id': '123'}
        result = process_payment(amount=100, user_id='u1')
        assert result['email_sent'] is True
        mock_email.assert_called_once()

def test_payment_email_failure():
    with patch('payment.send_email', side_effect=SMTPError('timeout')):
        result = process_payment(amount=100, user_id='u1')
        assert result['email_sent'] is False

Mockito Stub (Java)

import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.*;

class PaymentServiceTest {
    @Test
    void sendsReceiptOnSuccess() {
        EmailService emailMock = mock(EmailService.class);
        when(emailMock.send(any())).thenReturn(new Receipt("123"));
        PaymentService service = new PaymentService(emailMock);
        service.processPayment(100, "u1");
        verify(emailMock, times(1)).send(argThat(receipt ->
            receipt.getSubject().equals("Payment received")
        ));
    }
}

Explicación

  • Stubs: Proveen respuestas prefabricadas a llamadas. Un stub de base de datos podría devolver un registro de usuario hardcodeado. Los stubs reemplazan queries pero no verifican que las llamadas ocurrieron.
  • Mocks: Objetos pre-programados con expectativas. Un mock falla el test si no es llamado el número esperado de veces o con argumentos esperados. Usa mocks para verificar interacciones entre objetos.
  • Spies: Objetos reales que registran cada llamada para verificación posterior. Espía una caché real para confirmar que fue consultada antes de golpear la base de datos.

Variantes

DoubleReemplazaVerifica llamadasMejor para
DummyParámetro no usadoNoLlenar listas de argumentos
FakeImplementación funcionalNoBase de datos en memoria
StubRespuesta específicaNoDevolver datos de test
SpyObjeto real + registraVerificar side effects
MockInteracción esperadaVerificar llamadas hechas

Lo que funciona

  • Mock en el boundary, no internamente: mock el cliente HTTP o driver de base de datos, no cada método privado dentro de tu clase. Mock excesivo hace los tests frágiles.
  • Prefiere stubs para verificación de estado: si puedes assertar en el estado final (“el balance es $50”) en lugar de la interacción (“withdraw fue llamado una vez”), hazlo. Los tests basados en estado son más resilientes al refactoring.
  • Resetea mocks entre tests: el estado residual de mock de un test previo puede causar fallas confusas. Jest y Pytest manejan esto automáticamente; en otros frameworks, crea instancias frescas por test.
  • Usa inyección de dependencias: código que instancia sus propias dependencias con new Database() es difícil de mockear. Inyecta dependencias vía constructores o factories.
  • No mockees objetos de valor: clases simples de datos, structs y DTOs no tienen comportamiento para reemplazar. Pasa instancias reales.

Errores comunes

  • Mockear el sistema bajo test: mockear métodos dentro de la clase que estás testeando significa que no estás testeando la clase en absoluto. Mockea colaboradores, no el sujeto.
  • Especificar interacciones en exceso: verificar que database.connect() fue llamado exactamente una vez ata tu test a detalles de implementación. Testea outcomes, no mecánicas internas.
  • Ignorar verificación de mock: configurar mock.verify() pero nunca llamarlo en el cuerpo del test crea falsa confianza.
  • Usar mocks para todo: si cada clase está mockeada, tu suite de tests testea los mocks, no el sistema real. Mantén una mezcla saludable de tests unitarios y de integración.

Manejo de Errores en Tests

  • Manejo de test failures: maneja test failures con clear assertions. Usa descriptive assertion messages. Captura screenshots en UI test failures. Loggea test environment details en failure. Documenta failure handling strategy. Testea con known failing cases. Monitorea failure patterns. Alerta en unexpected pass rates. Revisa failing tests promptamente. Usa soft assertions para non-critical checks
  • Manejo de test timeouts: setea appropriate timeouts para cada test. Unit tests deberian completar en seconds. Integration tests pueden necesitar longer timeouts. E2E tests necesitan generous timeouts. Documenta timeout strategy. Testea timeout behavior. Monitorea timeout frequency. Alerta en timeout spikes. Revisa timeout values trimestralmente. Usa configurable timeouts
  • Gestion de flaky tests: identifica y fixea flaky tests. Trackea flaky test history. Quarantinea flaky tests. Fixea root cause de flakiness. Documenta flaky test strategy. Monitorea flaky test rate. Alerta en flaky test increases. Revisa quarantined tests regularmente. Prioriza flaky test fixes. Usa retry strategies cuidadosamente

Seguridad en Testing

  • Seguridad de test data: usa synthetic data para testing. Nunca uses real production data en tests. Maskea sensitive fields en test data. Encripta test databases. Documenta test data security strategy. Testea con different data sets. Monitorea test data access. Alerta en unauthorized access. Revisa test data regularmente. Usa data generation tools
  • Seguridad de test environments: asegura test environments. Usa separate credentials para test environments. Restringe access a test environments. Usa VPN para internal test environments. Documenta test environment security. Testea security controls. Monitorea access logs. Alerta en security violations. Revisa access permissions regularmente. Usa least privilege principle
  • Secrets en tests: nunca hardcodees secrets en test files. Usa environment variables para test secrets. Usa test-specific secret management. Rota test secrets regularmente. Documenta secrets management strategy. Testea con missing secrets. Monitorea secret usage. Alerta en secret exposure. Revisa secret handling code. Usa mock secrets para unit tests

Deployment y CI/CD para Tests

  • Diseno de test pipeline: disena CI/CD pipeline para tests. Corre unit tests en every commit. Corre integration tests en pull requests. Corre E2E tests antes de deployment. Corre security scans en every build. Documenta pipeline design. Testea pipeline performance. Monitorea pipeline success rate. Alerta en pipeline failures. Optimiza pipeline execution time
  • Test parallelization: paraleliza tests para faster execution. Usa test runners que soportan parallel execution. Agrupa tests por dependency. Aisla parallel tests. Documenta parallelization strategy. Testea parallel execution. Monitorea parallel test performance. Alerta en race conditions. Revisa parallelization configuration. Balancea parallelism y resource usage
  • Test result reporting: reporta test results claramente. Genera test reports en CI. Publica reports a stakeholders. Incluye test coverage en reports. Trackea test metrics en el tiempo. Documenta reporting strategy. Testea report format. Monitorea report accuracy. Alerta en report failures. Revisa report content regularmente

Tools y Platforms de Testing

  • Unit testing frameworks: elige el right unit testing framework. Jest para JavaScript. PyTest para Python. JUnit 5 para Java. Vitest para modern JavaScript. Documenta framework choice. Testea framework features. Monitorea framework performance. Revisa framework compatibility. Updatea framework versions regularmente. Usa framework-specific best practices
  • Integration testing tools: usa appropriate tools para integration testing. TestContainers para Docker-based integration tests. Supertest para API testing. WireMock para external service mocking. MSW para browser API mocking. Documenta tool selection. Testea tool compatibility. Monitorea tool performance. Revisa tool effectiveness. Updatea tools regularmente
  • E2E testing tools: elige el right E2E testing tool. Playwright para modern web E2E. Cypress para web applications. Selenium para legacy web apps. Detox para React Native. Documenta E2E tool choice. Testea E2E framework. Monitorea E2E test stability. Revisa E2E test coverage. Updatea E2E tools regularmente. Usa page object model

Pitfalls Comunes de Testing

  • Over-mocking: evita mockear demasiado. Mockea solo external dependencies. Mockea solo lo que necesitas controlar. Excessive mocking hace tests brittle. Documenta mocking strategy. Revisa mock usage regularmente. Refactoriza over-mocked tests. Monitorea test maintainability. Alerta en excessive mock count. Usa real implementations donde sea posible
  • Testear implementation details: testea behavior, no implementation. Evita testear private methods. Evita testear internal state. Focate en public API behavior. Documenta testing philosophy. Revisa tests para implementation coupling. Refactoriza implementation-coupled tests. Monitorea test refactoring needs. Educa team en behavior testing. Usa black-box testing approach
  • Ignorar edge cases: testea edge cases thoroughly. Testea empty inputs. Testea null values. Testea boundary conditions. Testea error paths. Documenta edge case testing strategy. Revisa edge case coverage. Monitorea edge case failures. Alerta en missing edge cases. Usa property-based testing para edge cases. Testea con random data

Best Practices

  • Convenciones de naming de tests: usa descriptive test names. Sigue arrange-act-assert pattern. Nombra tests por behavior, no implementation. Usa consistent naming across the suite. Documenta naming conventions. Revisa test names regularmente. Educa team en conventions. Monitorea naming compliance. Refactoriza poorly named tests. Usa standard prefixes como “should” o “when”
  • Organizacion de tests: organiza tests por feature o component. Agrupa related tests en describe blocks. Manten test files cerca de source files. Usa shared setup en beforeAll o beforeEach. Documenta test organization strategy. Revisa test file structure. Monitorea test file size. Refactoriza large test files. Usa helper functions para common setup. Manten tests independent
  • Gestion de test data: usa factories para test data. Usa builders para complex objects. Usa fixtures para static data. Usa seeders para database tests. Documenta test data strategy. Revisa test data usage. Monitorea test data maintenance. Refactoriza duplicated test data. Usa test data generators. Manten test data realistic pero synthetic
  • Test coverage goals: setea realistic coverage goals. 80% para critical paths. 60% para utility code. 100% para pure functions. Documenta coverage goals. Trackea coverage trends. Alerta en coverage drops. Revisa uncovered code. Prioriza coverage para high-risk code. Usa branch coverage sobre line coverage. Reporta coverage en CI

Optimizacion de Costos

  • Reduccion de test execution time: optimiza test execution speed. Usa parallel test execution. Minimiza database setup. Usa in-memory databases para unit tests. Cachea test dependencies. Documenta optimization strategy. Testea execution time regularmente. Monitorea test duration trends. Alerta en slow tests. Refactoriza slow tests. Usa test prioritization
  • Reduccion de test maintenance: minimiza test maintenance overhead. Escribe maintainable tests. Evita brittle assertions. Usa page object model para E2E. Refactoriza duplicated test code. Documenta maintenance strategy. Revisa test maintenance effort. Monitorea test code churn. Alerta en high maintenance tests. Usa shared test utilities. Manten tests DRY
  • Costos de test infrastructure: optimiza test infrastructure costs. Usa shared test environments. Usa containerized test environments. Escala test infrastructure con demand. Documenta cost optimization strategy. Monitorea infrastructure costs. Alerta en cost spikes. Revisa infrastructure usage. Usa spot instances para CI. Optimiza resource allocation

Guia de Troubleshooting

  • Debugging failing tests: aisla el failing test. Corre el test en isolation. Chequea test dependencies. Verifica test environment. Chequea race conditions. Documenta debugging steps. Usa debugging tools. Monitorea failure patterns. Alerta en recurring failures. Usa root cause analysis. Fixea root cause, no symptoms
  • Debugging slow tests: identifica slow tests. Profilea test execution. Chequea database queries. Chequea network calls. Chequea test setup. Documenta debugging steps. Usa profiling tools. Monitorea test duration. Alerta en slow tests. Optimiza slow operations. Usa async operations donde sea posible
  • Debugging de test environment issues: chequea environment configuration. Verifica dependencies estan installed. Chequea environment variables. Verifica database state. Chequea network connectivity. Documenta debugging steps. Testea environment setup. Monitorea environment health. Alerta en environment issues. Usa infrastructure as code. Manten environments consistent

Monitoring y Alerting

  • Key test metrics: trackea test pass rate, execution time, coverage y flaky test rate. Monitorea test count trends. Trackea test maintenance effort. Documenta metrics strategy. Configura dashboards para key metrics. Revisa metrics regularmente. Ajusta thresholds basado en trends. Alerta en critical metrics. Usa metrics para improvement decisions
  • Configuracion de alerts: setea alerts en test failure rate above 5%. Alerta en coverage drops. Alerta en flaky test rate increases. Alerta en test execution time spikes. Usa multi-level alerts: warning y critical. Documenta alert thresholds. Testea alert delivery. Revisa alert effectiveness mensualmente. Reduce alert noise. Usa runbooks para cada alert
  • Test reporting dashboards: crea dashboards para test metrics. Muestra pass rate, coverage y trends. Comparte con stakeholders. Updatea dashboards en real-time. Documenta dashboard strategy. Revisa dashboard content. Monitorea dashboard usage. Alerta en dashboard failures. Usa dashboards para decision making. Manten dashboards simple y focused

Patrones Avanzados de Testing

  • Property-based testing: usa property-based testing para edge case discovery. Define properties que deberian siempre hold. Deja al framework generar test cases. Corre many iterations para encontrar counterexamples. Documenta property-based testing strategy. Testea con different generators. Monitorea property test effectiveness. Revisa properties regularmente. Usa shrinking para debugging. Combina con example-based tests
  • Mutation testing: usa mutation testing para evaluar test quality. Mutatea source code y corre tests. Good tests catch mutations. Calcula mutation score. Documenta mutation testing strategy. Testea con different mutators. Monitorea mutation score trends. Revisa surviving mutants. Usa mutation testing para critical code. Balancea mutation testing cost y value
  • Snapshot testing: usa snapshot testing para regression detection. Captura component output como snapshot. Compara future runs contra snapshot. Revisa snapshot diffs cuidadosamente. Documenta snapshot testing strategy. Testea snapshot update process. Monitorea snapshot drift. Alerta en large snapshot changes. Usa snapshots para serializable output. Manten snapshots small y focused

Estrategias de Migracion

  • Migracion de manual a automated testing: empieza con critical paths. Automatiza smoke tests primero. Agrega integration tests despues. Agrega unit tests para new code. Gradualmente agrega tests para legacy code. Documenta migration strategy. Testea automation progress. Monitorea test coverage growth. Alerta en coverage stagnation. Revisa migration progress trimestralmente
  • Migracion entre test frameworks: planea framework migration cuidadosamente. Mapea old assertions a new framework. Migra tests incrementalmente. Corre ambos frameworks en paralelo. Documenta migration strategy. Testea migrated tests. Monitorea migration progress. Alerta en migration blockers. Completa migration despues de validation. Limpia old framework
  • Migracion de monolith a microservices testing: adapta test strategy para microservices. Agrega contract tests para service boundaries. Agrega integration tests para service interactions. Reduce E2E test scope. Documenta microservices testing strategy. Testea service contracts. Monitorea test execution. Alerta en contract violations. Revisa test architecture. Usa service virtualization

Compliance y Governance

  • Testing SLAs: define SLAs para test execution. Unit tests completan en under 5 minutos. Integration tests completan en under 30 minutos. E2E tests completan en under 60 minutos. Trackea SLA compliance. Alerta en SLA violations. Documenta SLA definitions. Revisa SLAs trimestralmente. Comunica SLA status. Usa SLA para priorizacion
  • Test reporting: genera weekly test reports. Incluye pass rate, coverage y trends. Highlighta flaky tests. Comparte con stakeholders. Documenta reporting methodology. Automatiza report generation. Revisa report content. Trackea metrics en el tiempo. Usa reports para planning y optimization
  • Audit y compliance: manten audit trail de test results. Trackea quien corrio tests y cuando. Loggea all test environment changes. Usa version control para test code. Documenta audit strategy. Testea audit log completeness. Monitorea audit log retention. Revisa compliance requirements regularmente. Alerta en audit log gaps

Automatizacion y Tooling

  • Test automation framework: construye un robusto test automation framework. Usa page object model para UI tests. Usa factory pattern para test data. Usa builder pattern para complex objects. Documenta framework architecture. Testea framework components. Monitorea framework performance. Revisa framework regularmente. Updatea framework con best practices. Manten framework maintainable
  • Automated test generation: usa tools para automated test generation. Genera unit tests desde code analysis. Genera API tests desde OpenAPI specs. Genera E2E tests desde user flows. Documenta generation strategy. Testea generated tests. Monitorea generation quality. Revisa generated tests. Edita generated tests. Usa generation para coverage gaps
  • Test data automation: automatiza test data generation. Usa factories para consistent data. Usa seeders para database setup. Usa mock servers para external APIs. Documenta automation strategy. Testea data automation. Monitorea data quality. Revisa automation effectiveness. Updatea automation regularmente. Manten data realistic

Sustentabilidad

  • Green testing: optimiza test energy consumption. Reduce unnecessary test runs. Usa incremental testing. Skipea tests para unchanged code. Usa parallel execution para reducir wall time. Documenta green testing strategy. Monitorea test energy usage. Revisa testing efficiency. Optimiza test resources. Usa cloud-native testing tools
  • Eficiencia de resources: optimiza test resource usage. Right-sizea test environments. Usa containerized tests. Comparte test resources across teams. Limpia test data despues de runs. Documenta resource efficiency strategy. Monitorea resource utilization. Revisa efficiency metrics. Optimiza resource allocation. Usa ephemeral environments
  • Reduccion de waste: reduce test waste. Deletea obsolete tests. Remueve duplicate tests. Limpia test artifacts. Remueve unused test data. Monitorea idle test resources. Documenta waste reduction strategy. Revisa test suite regularmente. Alerta en waste indicators. Automatiza cleanup procedures

Estándares de Industria y Frameworks

  • Testing standards: sigue industry testing standards. ISTQB para testing terminology. ISO/IEC 25010 para software quality. IEEE 829 para test documentation. Documenta standards usage. Testea compliance con standards. Monitorea standards adoption. Revisa standards regularmente. Entrena team en standards. Usa standards para test design
  • Test-driven development: practica TDD donde sea apropiado. Escribe tests antes de code. Red-green-refactor cycle. Empieza con failing test. Escribe minimal code para pass. Refactoriza despues de passing. Documenta TDD practices. Testea TDD adoption. Monitorea TDD effectiveness. Revisa TDD code quality. Usa TDD para critical features
  • Behavior-driven development: practica BDD para acceptance criteria. Escribe scenarios en Given-When-Then format. Usa Cucumber o SpecFlow para BDD. Documenta BDD practices. Testea BDD scenarios. Monitorea BDD adoption. Revisa BDD effectiveness. Usa BDD para user-facing features. Manten scenarios readable. Automatiza BDD scenarios

Reporting y Comunicacion

  • Performance reporting: genera weekly performance reports para test suites. Incluye execution time, pass rate, coverage y flaky test count. Compara con previous week. Highlighta trends y anomalies. Comparte con engineering team. Documenta reporting methodology. Automatiza report generation. Revisa report content mensualmente. Usa reports para optimization decisions
  • Cost reporting: genera monthly cost reports para testing infrastructure. Break down por environment, tool y team. Compara con budget. Identifica cost optimization opportunities. Comparte con stakeholders. Documenta cost reporting strategy. Automatiza cost report generation. Revisa cost trends trimestralmente. Usa reports para budget planning
  • Incident reporting: documenta all test-related incidents. Incluye root cause, impact y resolution. Comparte incident reports con team. Conduce post-mortem reviews. Documenta action items. Trackea action item completion. Revisa incident patterns. Usa incidents para improvement. Comunica incidents a stakeholders. Manten incident history

Optimizacion Avanzada

  • Test suite optimization: optimiza test suite para speed y reliability. Remueve duplicate tests. Mergea similar tests. Skipea tests para unchanged code. Usa test prioritization. Documenta optimization strategy. Testea suite performance. Monitorea execution time. Alerta en slow suites. Revisa suite regularmente. Manten suite lean
  • Test environment optimization: optimiza test environments para speed. Usa containerized environments. Usa in-memory databases. Usa mock services. Cachea environment setup. Documenta optimization strategy. Testea environment performance. Monitorea environment health. Alerta en environment issues. Revisa environments regularmente
  • Test data optimization: optimiza test data para speed y reliability. Usa minimal data sets. Usa factories para on-demand data. Usa seeders para consistent state. Cachea test data. Documenta optimization strategy. Testea data performance. Monitorea data quality. Alerta en data issues. Revisa test data regularmente. Manten data minimal

Patrones de Arquitectura de Tests

  • Piramide de tests: sigue el test pyramid pattern. Many unit tests en la base. Fewer integration tests en el medio. Very few E2E tests en el top. Unit tests son fast y isolated. Integration tests cubren boundaries. E2E tests cubren critical user flows. Documenta test pyramid adoption. Monitorea test distribution. Alerta en pyramid inversion. Revisa test mix regularmente
  • Test diamond: usa test diamond para service-oriented architecture. Few unit tests. Many contract tests. Few E2E tests. Contract tests verifican service boundaries. Documenta test diamond usage. Monitorea test distribution. Alerta en missing contract tests. Revisa test architecture. Adapta a service complexity
  • Testing honeycomb: usa testing honeycomb para microservices. Few unit tests. Many integration tests. Few E2E tests. Integration tests cubren service interactions. Documenta honeycomb pattern. Monitorea test distribution. Alerta en architecture mismatch. Revisa test strategy. Adapta a architecture changes

Estrategias de Test Data

  • Test data factories: usa factories para test data creation. Centraliza data creation logic. Usa builders para complex objects. Usa default values con overrides. Documenta factory pattern usage. Testea factory output. Monitorea factory maintenance. Revisa factories regularmente. Refactoriza duplicated factories. Manten factories simple y composable
  • Test data seeders: usa seeders para database test data. Crea consistent test state. Corre seeders antes de test suites. Limpia despues de tests. Documenta seeding strategy. Testea seeding performance. Monitorea seeding reliability. Revisa seed data regularmente. Optimiza seeding speed. Usa transactions para cleanup
  • Test data fixtures: usa fixtures para static test data. Storea fixtures en JSON o YAML. Carga fixtures en test setup. Manten fixtures small y focused. Documenta fixture strategy. Testea fixture loading. Monitorea fixture maintenance. Revisa fixtures regularmente. Updatea fixtures cuando schema cambia. Usa fixtures para regression tests

Mantenimiento de Tests

  • Calidad de test code: mantiene high code quality en tests. Sigue same coding standards que production code. Usa meaningful variable names. Manten tests readable. Refactoriza test code regularmente. Documenta quality standards. Revisa test code en PRs. Monitorea test code metrics. Alerta en quality degradation. Usa linting para test code
  • Gestion de test debt: trackea y maneja test debt. Identifica tests que necesitan refactoring. Prioriza test debt items. Schedulea regular test refactoring. Documenta test debt strategy. Monitorea test debt backlog. Alerta en growing test debt. Revisa test debt trimestralmente. Aloca time para test debt. Manten test debt visible
  • Documentacion de tests: documenta test strategy y conventions. Documenta test architecture decisions. Documenta test data strategy. Documenta test environment setup. Manten documentation updated. Revisa documentation regularmente. Monitorea documentation accuracy. Alerta en outdated docs. Usa inline documentation. Manten docs cerca de code

Colaboracion del Team

  • Test reviews: revisa tests en pull requests. Chequea test coverage para new code. Verifica test quality. Chequea edge cases. Revisa test naming. Documenta review checklist. Entrena team en test reviews. Monitorea review effectiveness. Alerta en missing test reviews. Usa test review templates
  • Knowledge sharing: comparte testing knowledge across el team. Conduce testing lunch-and-learns. Comparte testing best practices. Documenta testing patterns. Crea testing guidelines. Monitorea knowledge sharing. Revisa team testing skills. Alerta en knowledge gaps. Usa pair testing. Mentorea junior developers
  • Testing culture: construye una strong testing culture. Celebra testing achievements. Reconoce good test practices. Encourages test-first development. Haz testing visible. Documenta culture initiatives. Monitorea testing culture. Revisa team engagement. Alerta en culture degradation. Lidera by example

Preguntas frecuentes

P: ¿Cuándo debería usar una dependencia real en lugar de un mock? R: Cuando la dependencia es rápida, determinística y simple — por ejemplo, un Map en memoria o una función pura. Mientras más cercano esté tu test a producción, más confianza provee.

P: ¿Cuál es la diferencia entre un stub y un mock? R: Un stub responde llamadas con datos preset. Un mock verifica que se hicieron llamadas esperadas. Puedes usar un mock como stub, pero no viceversa.

P: ¿Debería mockear el sistema de archivos? R: Para tests unitarios, sí — usa sistemas de archivos virtuales o streams en memoria. Para tests de integración, escribe a un directorio temporal y limpia después.

P: ¿Puedo mockear métodos estáticos? R: En Java, PowerMock y Mockito inline mock pueden hacerlo, pero es desalentado. Los métodos estáticos son difíciles de testear porque no pueden inyectarse. Refactoriza a métodos de instancia cuando sea posible.

¿Esta solución está lista para producción?

Sí. Los ejemplos de código arriba muestran implementaciones probadas. Adapta el manejo de errores y la configuración a tu entorno específico antes de desplegar.

¿Cuáles son las características de rendimiento?

El rendimiento depende de tu volumen de datos e infraestructura. Las soluciones mostradas priorizan claridad. Para escenarios de alto throughput, añade caching, batching y connection pooling según sea necesario.

¿Cómo depuro problemas con este enfoque?

Empieza con el ejemplo mínimo de arriba. Añade logging en cada paso. Prueba con entradas pequeñas primero, luego escala. Usa el debugger de tu lenguaje para revisar los edge cases.

¿Cuáles son las limitaciones de mocking en unit tests?

Mocking tiene algunas limitations. Excessive mocking hace tests brittle. Mocks pueden divergir de real implementations. Mocks necesitan mantenimiento cuando interfaces cambian. Mocks pueden dar false confidence. Documenta limitations para tu team. Planean mitigation strategies. Testea con real implementations en integration. Monitorea mock maintenance overhead.

¿Cuándo debo usar mocking vs real implementations?

Usa mocking para unit tests de components aislados. Usa real implementations para integration tests. Usa mocking cuando external dependencies son lentas o inestables. Usa real implementations cuando necesitas validar behavior end-to-end. Documenta decision criteria para tu team.