Prueba de unidad con monkey patch en Angular (No se pueden leer las propiedades de undefined (leyendo ‘checkABC’))
Estoy intentando probar unitariamente mi método setStep() en angular usando Jasmine, pero sigo obteniendo “Cannot read properties of undefined (reading ‘checkBusiness’)” lo cual me impide continuar con la prueba.
Esta es la función en el archivo component.ts:
get userBusiness(): string { return this.auth && this.auth.user && this.auth.user.Source; }
setSteps() {
if (this.userBusiness.checkBusiness('ABC')) {
this.items = steps['ABC'];
if (this.application.process.onboarding.status !== 'complete') { this.show = true; }
} else {
this.items = steps['DEF'];
}
}
El método “checkBusiness()” está definido como un monkey patch para la clase prototype de String:
Interface String {
checkBusiness(...args: string[]): boolean;
}
String.prototype.checkBusiness = function(...args: string[]): boolean {
let result = false;
for (let arg of args) {
const currentBusinessArray = business[this];
if (!currentBusinessArray) {
result = false;
continue;
}
if (currentBusinessArray.includes(arg)) {
result = true;
}
}
return result;
};
“Business” es un array definido de la siguiente manera:
const lob = Object.freeze(
ABC: [‘ABC’, ‘ABC1’, ‘ABC2’, ‘ABC3’],
DEF: [‘DEF’, ‘DEF1’, ‘DEF2’, ‘DEF3’]
});
Archivo de prueba (spec):
it('should confirm that "show" is set to true in setSteps()', () => {
const testUserBusiness = {...testDataSvc.userABC}
const userBusinessSpy = spyOnProperty(component, 'userBusiness').and.returnValue(testUserBusiness);
console.log(component['userBusiness']);
component.setSteps();
})
Problema:
Sigo obteniendo “Cannot read properties of undefined (reading ‘checkBusiness’)”.
¿Alguna idea de cómo superar esto? He intentado buscar en todas partes pero no hay un escenario similar que pueda seguir.
davy.ai
Parece que el error se debe al hecho de que el método
checkBusiness()
no está definido en el prototipo deString
dentro del entorno de prueba unitaria. Tiene sentido, ya que parchear los prototipos integrados generalmente se considera una mala práctica.Un par de opciones para solucionar este problema:
checkBusiness()
en una función de utilidad separada que se pueda importar fácilmente tanto en el archivo del componente como en el archivo de prueba unitaria.Por ejemplo:
Luego puedes importar esta función en el archivo del componente y usarla de la siguiente manera:
Y en el archivo de prueba unitaria:
Ten en cuenta que en el archivo de prueba estamos usando el método
spyOn()
para simular la funcióncheckBusiness()
y devolver un valor detrue
con fines de prueba.checkBusiness()
directamente en el prototipo deString
dentro del archivo de prueba unitaria, agregando el siguiente código:Esto debería solucionar el problema con la prueba unitaria actual, pero como se mencionó anteriormente, no es una buena práctica modificar los prototipos integrados de esta manera.
Se recomienda utilizar la primera opción y refactorizar el método
checkBusiness()
en una función de utilidad separada.