angular - Probar un Pipe de Angular2 que tiene un método constructor en Jasmine
Estoy fallando en el primer obstáculo al probar un Pipe de Angular que tiene un constructor.
Mi tubería es la siguiente:
reverse.pipe.ts
import {
IterableDiffer,
IterableDiffers,
Pipe,
PipeTransform
} from '@angular/core';
@Pipe({
name: 'reverse',
pure: false
})
export class ReversePipe implements PipeTransform {
private cached: Array<any>;
private differ: IterableDiffer<Array<any>>;
constructor(private differs: IterableDiffers) {
this.differ = this.differs.find([]).create(null);
}
transform(array: Array<any>): Array<any> {
// TODO: Throw an error if `array` isn't an Array
if (Array.isArray(array) === false) return [];
const changes = this.differ.diff(array);
if (changes) this.cached = array.slice().reverse();
return this.cached;
}
}
Creo, a través de varios tutoriales, que es correcto usar un IterableDiffer por eficiencia. Pero ese no es el tema de esta pregunta.
El hecho de que se requiera un constructor, creo que es la raíz de que esta prueba simple falle:
reverse.pipe.spec.ts
import { ReversePipe } from './reverse.pipe';
describe('ReversePipe', () => {
it('create an instance', () => {
const pipe = new ReversePipe();
expect(pipe).toBeTruthy();
});
});
La prueba falla con el error: TypeError: Cannot read property 'find' of undefined
Esto (probablemente de manera incorrecta) asumo que se debe a que differs necesita inyectarse en la prueba, ya que el mensaje de error sugiere que es undefined.
¿Estoy en lo correcto y cómo debería escribir una prueba simple para el Pipe?
Actualizar
He intentado inyectar IterableDiffers en el Pipe que se está probando; aunque eso ha rectificado el error anterior, ahora me enfrento a uno nuevo Error: No se pueden resolver todos los parámetros para IterableDiffers: (?).
En la terminal, se muestra el error No se puede invocar una expresión cuyo tipo carece de una firma de llamada. El tipo 'IterableDiffers' no tiene firmas de llamada compatibles..
Ambos están describiendo el mismo problema solo en diferente idioma.
Mi prueba actualizada es:
reverse.pipe.spec.ts
import { IterableDiffer, IterableDiffers } from '@angular/core';
import { TestBed, inject } from '@angular/core/testing';
import { ReversePipe } from './reverse.pipe';
describe('ReversePipe', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [IterableDiffers]
});
});
// it('create an instance', () => {
// const array = [ 1, 2, 3 ];
// const pipe = new ReversePipe(new IterableDiffers);
// expect(pipe).toBeTruthy();
// });
it('create an instance', inject([IterableDiffers], (iterableDiffers: IterableDiffers) => {
const array = [ 1, 2, 3 ];
const pipe = new ReversePipe(iterableDiffers);
expect(pipe).toBeTruthy();
}));
});
Cualquier tipo de ayuda es muy apreciada.
Respuesta #1
Estuve muy cerca con mi prueba actualizada. No necesitas proporcionar IterableDiffers:
reverse.pipe.spec.ts
import { IterableDiffers } from '@angular/core';
import { TestBed, inject } from '@angular/core/testing';
import { ReversePipe } from './reverse.pipe';
describe('ReversePipe', () => {
it('should create an instance', inject([ IterableDiffers ], (iterableDiffers: IterableDiffers) => {
const pipe = new ReversePipe(iterableDiffers);
expect(pipe).toBeTruthy();
}));
it('should reverse the array of type Array<number>', inject([ IterableDiffers ], (iterableDiffers: IterableDiffers) => {
const array = [ 1, 2, 3 ];
const pipe = new ReversePipe(iterableDiffers);
expect(pipe.transform(array)).toEqual([ 3, 2, 1 ]);
}));
it('should reverse the array of type Array<string>', inject([ IterableDiffers ], (iterableDiffers: IterableDiffers) => {
const array = [ 'apple', 'banana', 'clementine' ];
const pipe = new ReversePipe(iterableDiffers);
expect(pipe.transform(array)).toEqual([ 'clementine', 'banana', 'apple' ]);
}));
});
También noté que tenía una declaración if innecesaria en reverse.pipe.spec.ts:
// TODO: Throw an error if `array` isn't an Array
if (Array.isArray(array) === false) return [];
El primer argumento de transform siempre sería un Array; por supuesto, el compilador de TypeScript lanzaría un TypeError si el argumento fuera cualquier cosa que no fuera un Array.
Para mayor completitud, mi tubería es:
reverse.pipe.ts
import {
IterableDiffer,
IterableDiffers,
Pipe,
PipeTransform
} from '@angular/core';
@Pipe({
name: 'reverse',
pure: false
})
export class ReversePipe implements PipeTransform {
private cached: Array<any>;
private differ: IterableDiffer<Array<any>>;
constructor(private differs: IterableDiffers) {
this.differ = this.differs.find([]).create(null);
}
public transform(array: Array<any>): Array<any> {
const changes = this.differ.diff(array);
if (changes) this.cached = array.slice().reverse();
return this.cached;
}
}
