Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

En una arquitectura Vertical Slice dentro de una sola Web API, las convenciones no se hacen cumplir por el mero hecho de organizar el código en slices: conviene convertirlas en pruebas ejecutables. En la tercera y última entrega de su serie sobre VSA en .NET, Beto Ramirez combina tests de arquitectura, pruebas de handlers con SQLite in-memory y contratos OpenAPI generados para el frontend. También propone una ruta de evolución condicional: extraer módulos cuando haya motivos y considerar microservicios solo si la independencia de despliegue o escalado lo justifica.

Qué problema resuelven los tests de arquitectura

Separar los casos de uso por feature ayuda a mantener cada slice cohesivo, pero no impide que alguien con prisa llame directamente al caso de uso de otro slice, que aparezcan dependencias circulares o que el código compartido termine dependiendo de features concretas. Los tests de arquitectura convierten ciertas reglas del diseño en verificaciones automatizadas: no sustituyen una buena estructura, pero pueden detectar cuándo el código deja de respetarla.

El artículo de Ramirez plantea seis reglas para su diseño:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Un slice no debe utilizar los casos de uso de otro slice.
  • El espacio común Common no debe depender de casos de uso de slices.
  • Las clases de endpoints deben implementar la interfaz de registro de endpoints establecida por el proyecto.
  • Los event handlers deben residir dentro de slices de features.
  • Los contratos anidados deben respetar nombres como Request, Response o Validator.
  • Los handlers deben cumplir la convención de registro indicada por la arquitectura.

La intención no es prohibir dependencias útiles entre cualquier componente, sino proteger límites concretos: quién puede invocar un caso de uso, dónde viven los handlers y cómo se registra la superficie HTTP. Las reglas exactas dependen de los namespaces, interfaces y convenciones del proyecto; no son un conjunto universal que pueda copiarse sin adaptación.

Verificar que las reglas realmente detectan infracciones

Una prueba de arquitectura que siempre pasa puede dar una falsa sensación de seguridad. Ramirez resume la lección con esta frase: “Un test de arquitectura que nunca falla no protege nada.” Durante el desarrollo, introducir deliberadamente una infracción —por ejemplo, una referencia de un slice a otro— permite comprobar que la regla falla por el motivo esperado. Después se revierte el cambio de prueba y se conserva la regla como parte de la suite automatizada.

Probar handlers con SQLite in-memory

Para probar un handler que interactúa con datos, la serie propone SQLite in-memory con Entity Framework Core en vez de sustituir el acceso a datos por un repositorio simulado. Esa elección permite ejecutar SQL relacional y trabajar con el esquema que la prueba crea. No equivale a probar contra la base de datos de producción: el proveedor, el esquema y los comportamientos específicos pueden diferir.

Qué hace el ejemplo

El patrón descrito abre una conexión SQLite en memoria, configura EF Core con UseSqlite, crea el esquema mediante EnsureCreated() y entrega el contexto resultante a la prueba del handler. La conexión debe mantenerse abierta mientras se usa la base en memoria, pues su ciclo de vida está ligado a ella.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

En el ejemplo se conserva un dispatcher simulado en el límite externo. Por tanto, la propuesta no es “hacer real todo”: se usa una base relacional para la parte que se quiere ejercitar y se mantiene falso el componente externo que no forma parte del foco de esa prueba.

Qué cubre y qué no

  • SQL y esquema de prueba: permite ejercitar consultas y operaciones relacionales sobre el esquema que se crea para el test, en lugar de verificar solo interacciones con un mock.
  • Comportamiento del proveedor: SQLite ofrece comportamiento relacional, pero no reproduce necesariamente dialecto, restricciones, tipos o particularidades del proveedor de producción.
  • Velocidad: el artículo presenta esta configuración como una opción práctica para tests de handlers, pero no publica benchmarks que permitan afirmar cuánto más rápida o lenta es frente a otras alternativas.
  • Límites externos: el dispatcher sigue simulado en el ejemplo; el test no verifica por ello el envío real de eventos ni la integración completa del sistema.

Si un comportamiento depende de una característica propia de la base de producción, la prueba con SQLite no basta para demostrarlo: esa diferencia requiere una comprobación específica con el proveedor pertinente. La estrategia descrita es útil para reducir el uso de mocks en la capa de datos, no como garantía de equivalencia entre bases.

Conectar los contratos de la API con Angular

Para reducir la duplicación manual de tipos entre backend y frontend, la serie propone emitir un documento OpenAPI y generar tipos y clientes para Angular con ng-openapi-gen. Así, el contrato publicado por la API puede alimentar el código TypeScript en vez de mantener a mano definiciones paralelas que pueden quedar desactualizadas.

El flujo también atiende un problema de nombres: varios endpoints pueden tener clases anidadas llamadas Request o Response. La personalización del nombre de esquema en OpenAPI ayuda a evitar colisiones en los tipos generados. El artículo combina esa configuración con nombres explícitos para endpoints y resultados tipados.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Son detalles de implementación de la serie, no instrucciones universales garantizadas para cualquier versión. Antes de adoptar el ejemplo, hay que comprobar que las opciones de generación, el formato OpenAPI emitido y las convenciones del proyecto coinciden con las versiones reales de .NET, EF Core y las herramientas usadas. La generación reduce el trabajo de mantener contratos duplicados, pero no elimina la necesidad de revisar los cambios generados y la compatibilidad de la API.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Cómo puede evolucionar una aplicación con más slices

Ramirez presenta una secuencia de crecimiento como posibilidad, no como una migración obligatoria ni como una promesa de que extraer módulos no requerirá refactorización. El criterio central es que la estructura responda a cohesión y necesidades operativas reales, no a una cifra aislada de slices.

  1. Una Web API con slices: mantener los casos de uso organizados por feature dentro de un proyecto mientras la solución y el equipo puedan trabajar eficazmente con esa organización.
  2. Extraer una feature como módulo: cuando una parte crece y gana cohesión propia, separarla como módulo puede hacer más claros sus límites y responsabilidades.
  3. Modular monolith: si varios módulos requieren comunicación más resiliente, incorporar mensajería asíncrona puede ayudar, a cambio de gestionar entrega, fallos y operación de mensajes.
  4. Microservicio: considerarlo cuando la necesidad de escalar o desplegar de manera independiente justifique la complejidad operativa y distribuida adicional.

Para decidir si avanzar, conviene valorar si hay límites de módulo comprensibles, ownership de equipo diferenciado, necesidad de despliegue independiente y una razón concreta para asumir la mensajería y operación distribuidas. Un recuento alto de slices, por sí solo, no demuestra que haga falta un servicio separado.

Qué aporta esta combinación y dónde están sus límites

La propuesta une tres controles distintos: tests de arquitectura para reglas de dependencia y registro, pruebas con SQLite para ejercitar SQL relacional en handlers, y generación OpenAPI para compartir contratos con Angular. Cada uno cubre un riesgo diferente; ninguno certifica por sí solo que toda la arquitectura, la base de producción o la integración frontend-backend sean correctas.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Los ejemplos y la ruta de evolución pertenecen a la tercera entrega de la serie de Ramirez sobre VSA en .NET. No se presentan aquí como una receta validada para todas las versiones o proyectos: las convenciones y opciones concretas deben contrastarse con el stack y los límites que cada aplicación necesita.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.