Pruebas e integración
Parte de la sección Programación Orientada a Objetos del Journey de GO de Coddy — lección 104 de 107.
Desafío
Fácil¡Vamos a completar nuestro Sistema de Gestión de Biblioteca escribiendo pruebas que verifiquen que todo funciona correctamente! Crearás un archivo de prueba que valide la funcionalidad principal de tu biblioteca, asegurando que los libros se puedan tomar prestados y devolver adecuadamente, y que las condiciones de error se manejen de forma correcta.
Organizarás tu código en cinco archivos:
book.go: Tu structBookcon los camposID,Title,Author,ISBNyAvailable. Incluye el constructorNewBookque inicializa los libros como disponibles.user.go: Tu structUsercon los camposID,Name,EmailyBorrowedBooks. Incluye el constructorNewUser.library.go: Tu structLibrarycon mapas para libros y usuarios, junto con los métodosNewLibrary,AddBook,AddUser,BorrowyReturn. El métodoBorrowdebe devolver errores para un usuario inválido, un libro inválido o un libro no disponible. El métodoReturndebe devolver errores para un usuario inválido, un libro inválido o un libro no prestado.library_test.go: ¡Aquí es donde escribirás tus funciones de prueba! Crea pruebas que verifiquen:TestBorrowSuccess— Verifica que tomar prestado un libro disponible sea exitoso (no se devuelve error), el libro pase a estar no disponible y el ID del libro se agregue a la lista de prestados del usuario.TestBorrowUnavailable— Verifica que intentar tomar prestado un libro que ya está prestado devuelva un error.TestBorrowInvalidUser— Verifica que intentar tomar prestado con un ID de usuario inexistente devuelva un error.TestReturnSuccess— Verifica que devolver un libro prestado sea exitoso, el libro vuelva a estar disponible y el ID del libro se elimine de la lista de prestados del usuario.
Cada prueba debe configurar su propia biblioteca con los libros y usuarios necesarios, realizar la operación y comprobar los resultados utilizando
t.Errorot.Errorfcuando las aserciones fallen.main.go: Ejecuta tus pruebas manualmente e informa los resultados. Lee el nombre de la prueba a ejecutar (borrow_success,borrow_unavailable,borrow_invalid_useroreturn_success). Basándote en el nombre de la prueba, configura el escenario apropiado e imprimePASSsi todas las aserciones pasan, oFAIL: [reason]si alguna aserción falla.
Se proporcionará la siguiente entrada:
- Un nombre de prueba:
borrow_success,borrow_unavailable,borrow_invalid_useroreturn_success
Para cada prueba, utiliza estos datos de prueba estándar (fixtures):
- Libro: ID
B001, TitleGo Programming, AuthorJohn Doe, ISBN123-456 - Usuario: ID
U001, NameAlice, Emailalice@test.com
Por ejemplo, dado:
borrow_successTu salida debería ser:
PASSY dado:
borrow_unavailableTu salida debería ser:
PASSY dado:
borrow_invalid_userTu salida debería ser:
PASSY dado:
return_successTu salida debería ser:
PASSPara borrow_success: Crea la biblioteca, añade el libro y el usuario, toma prestado el libro, verifica que no haya error, verifica que el libro no esté disponible, verifica que el usuario tenga el libro en su lista de prestados.
Para borrow_unavailable: Crea la biblioteca, añade el libro y el usuario, establece el campo Available del libro a false, intenta tomarlo prestado, verifica que se devuelva un error.
Para borrow_invalid_user: Crea la biblioteca, añade solo el libro (sin usuario), intenta tomarlo prestado con el ID de usuario U001, verifica que se devuelva un error.
Para return_success: Crea la biblioteca, añade el libro y el usuario, toma prestado el libro primero, luego devuélvelo, verifica que no haya error, verifica que el libro esté disponible de nuevo, verifica que la lista de prestados del usuario esté vacía.
¡Escribir pruebas asegura que tu sistema de biblioteca se comporte correctamente y te da confianza para realizar cambios sin romper la funcionalidad existente!
Pruébalo tú mismo
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
testName, _ := reader.ReadString('\n')
testName = strings.TrimSpace(testName)
// Accesorios de prueba estándar
// Book: ID "B001", Title "Go Programming", Author "John Doe", ISBN "123-456"
// User: ID "U001", Name "Alice", Email "alice@test.com"
switch testName {
case "borrow_success":
// TODO: Probar que tomar prestado un libro disponible tiene éxito
// 1. Crear la biblioteca, añadir el libro y el usuario
// 2. Tomar prestado el libro
// 3. Verificar: sin errores, libro no disponible, el usuario tiene el libro en su lista
// Imprimir "PASS" si todo pasa, o "FAIL: [reason]" si algo falla
fmt.Println("FAIL: not implemented")
case "borrow_unavailable":
// TODO: Probar que tomar prestado un libro no disponible devuelve un error
// 1. Crear la biblioteca, añadir el libro y el usuario
// 2. Establecer Available del libro a false
// 3. Intentar tomar prestado
// 4. Verificar que se devuelve un error
fmt.Println("FAIL: not implemented")
case "borrow_invalid_user":
// TODO: Probar que tomar prestado con un usuario inválido devuelve un error
// 1. Crear la biblioteca, añadir solo el libro (sin usuario)
// 2. Intentar tomar prestado con el ID de usuario "U001"
// 3. Verificar que se devuelve un error
fmt.Println("FAIL: not implemented")
case "return_success":
// TODO: Probar que devolver un libro prestado tiene éxito
// 1. Crear la biblioteca, añadir el libro y el usuario
// 2. Tomar prestado el libro primero
// 3. Devolver el libro
// 4. Verificar: sin errores, libro disponible, la lista del usuario está vacía
fmt.Println("FAIL: not implemented")
default:
fmt.Println("FAIL: unknown test")
}
}
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de POO en Go
Archivos externosEspacio de trabajo y módulos de GoPaquetes e importacionesNombres exportados vs. no exportadosIntroducción a la POO en GoStructs como clasesDefinición de métodos en structsReceptores de puntero vs. de valorInicialización de structsFunciones constructorasResumen - Calculadora simple4Interfaces
Introducción a las interfacesImplementación implícitaLa interfaz como contratoInterfaz vacía (any)Type AssertionType SwitchComposición de interfacesInterfaces Stringer y ErrorResumen: Calculadora de figuras7Encapsulamiento
Campos exportados vs. no exportadosEncapsulamiento a nivel de paqueteMétodos Getter y SetterOcultamiento de información en GoResumen - Registros de estudiantes10Genéricos (Go 1.18+)
Introducción a los GenéricosParámetros de tipoRestricciones de tipoStructs genéricosSolución alternativa para métodos genéricosResumen - Colección genérica13Patrones de diseño - Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón Abstract FactoryPatrón ObserverPatrón Strategy2Inmersión profunda en Tipos y Structs
Tipos básicos y compuestosDefiniciones de tipos personalizadosEtiquetas de StructsStructs anónimosStructs anidadosValores cero y por defectoRepaso - Libreta de contactos5Composición sobre herencia
Por qué Go no tiene herenciaConceptos básicos de incrustación de structsPromoción de métodosIncrustación de múltiples structsIncrustación vs AgregaciónShadowing de métodos incrustadosResumen - Jerarquía de empleados8Manejo de Errores y OOP
La interfaz errorTipos de errores personalizadosEnvoltura de errores (fmt.Errorf)Errores centinelaerrors.Is() y errors.As()Panic, Defer y RecoverResumen - Analizador de archivos3Punteros y Memoria
Fundamentos de punteros en GoPunteros a StructsPaso por valor vs referenciaLa función new()Garbage Collection en GoResumen - Constructor de Linked List6Polimorfismo en Go
Polimorfismo mediante interfacesDuck Typing en GoReglas de satisfacción de interfacesColecciones polimórficasInyección de dependenciasResumen - Procesador de pagos9Concurrencia y POO
Fundamentos de GoroutinesChannels y comunicaciónChannels con buffer vs. sin bufferSentencia Selectsync.Mutex y sync.RWMutexsync.WaitGroupDiseño de estructuras Thread-SafeResumen - Worker Pool12Conceptos avanzados de POO
Patrón Functional OptionsPatrón Builder en GoEncadenamiento de métodosAlias de tipos vs. definicionesFundamentos de ReflectionDescripción general de generación de código15Proyecto: Gestión de bibliotecas
Descripción general y estructura del proyectoStructs de libros y usuarios