tengo una funcion
handleCSV () { this.storeData$.take(1).subscribe(s => { const data = s.data const fields = ['reference', 'description', 'val1', 'val2', 'difference'] const fieldNames = ['Reference', 'Description', 'Value 1', 'Value 2', 'Difference'] const exportData = data.filter(dataset => dataset.visible) const csv = json2csv({ data: exportData, fields: fields, fieldNames: fieldNames }) const csvEnc = encodeURIComponent(csv) const href = `data:application/octet-stream,${csvEnc}` this.csvDownloadLink.nativeElement.setAttribute('href', href) this.csvDownloadLink.nativeElement.click() this.csvDownloadLink.nativeElement.setAttribute('href', '') }) }Casi tengo una cobertura del 100% de esta función, lo único que falta es la devolución de llamada data.filter
¿Alguien sabe cómo probar esto? La biblioteca de prueba utilizada es Jasmine, la aplicación en general está construida con Angular. Aquí está la prueba que tengo actualmente que me ha llevado al nivel actual de cobertura (cualquier otro comentario sobre esto también es bienvenido):
it('should click the CSV link', () => { spyOn(comp.csvDownloadLink.nativeElement, 'click') comp.ngOnInit() comp.handleCSV() expect(comp.csvDownloadLink.nativeElement.click).toHaveBeenCalledTimes(1) })Editar
De acuerdo, descubrí que la causa del problema no es que no se llame a la devolución de llamada data.filter, ¡sino que la matriz de datos en sí está vacía! Por ejemplo, al asegurarse siempre de que la matriz de datos tenga algo, la devolución de llamada está cubierta:
Ahora, obviamente, no quiero esta declaración if en mi código, así que supongo que mi pregunta se convierte en esta: ¿cómo puedo, con el propósito de probar, asegurarme siempre de que storeData$ tenga algo en él? Ahora esto ha cambiado el alcance de la pregunta, ahora es una pregunta de prueba ngrx. La función ngOnInit() activa una acción que llena de forma asincrónica storeData$, pero obviamente esto no sucede en la prueba. Entonces, ¿cómo puedo activar la función ngOnInit() y asegurarme de que el reductor haya regresado y que storeData$ se complete cuando llame a handleCSV()?
storeData$ no 'contiene' datos. storeData$ emitirá valores a lo largo del tiempo y, al suscribirse, tiene una forma de manejar esos valores a medida que llegan. En su caso, solo maneja el primer valor que llega (con la función take(1) ).
Su función de flecha que maneja cada nuevo valor tiene bastante lógica. En mi opinión, debe extraer esta función de flecha a una función con nombre que se puede probar por separado. De esta manera, puede probar la lógica sin tener que preocuparse por storeData$ .
handleCSV () { this.storeData$.take(1).subscribe(this.onNewStoreData); } onNewStoreData(s) { const data = s.data const fields = ['reference', 'description', 'val1', 'val2', 'difference'] const fieldNames = ['Reference', 'Description', 'Value 1', 'Value 2', 'Difference'] const exportData = data.filter(dataset => dataset.visible) const csv = json2csv({ data: exportData, fields: fields, fieldNames: fieldNames }) const csvEnc = encodeURIComponent(csv) const href = `data:application/octet-stream,${csvEnc}` this.csvDownloadLink.nativeElement.setAttribute('href', href) this.csvDownloadLink.nativeElement.click() this.csvDownloadLink.nativeElement.setAttribute('href', '') }