web-dev-qa-db-fra.com

Comment se moquer de ActivatedRouteSnapshot lors du test d'unité d'un résolveur

Je veux écrire un test unitaire pour mon résolveur, qui doit prendre ActivatedRouteSnapshot dans son constructeur comme ceci:

export class MyResolver {
  constructor () {
    // ...
  }

  resolve (private route: ActivatedRouteSnapshot) {
    callFoo(route.params.val);
  }
};

Mais dans mon test unitaire, quelle est la meilleure façon de fournir un instantané d'itinéraire activé avec des données fictives? Lorsque j'essaie de créer un objet avec uniquement les propriétés dont j'ai besoin, j'obtiens une erreur indiquant qu'il ne peut pas être converti en ActivatedRouteSnapshot:

it('should call foo', inject([MyResolver], async (myResolver: MyResolver) => {
  const mockRoute = {
    params: {
      val: '1234'
    };
  };

  sinon.spy(callFoo);
  myResolver.resolve(mockRoute); // This is the line that errors
  expect(callFoo.calledWith('1234')).to.be.true;
}));

Erreur:

Type '{ params: { val: string; }; }' cannot be converted to type 'ActivatedRouteSnapshot'.

Comment puis-je fournir un faux ActivatedRouteSnapshot à transmettre à mon résolveur?

14
A. Duff

Vous devez fournir l'itinéraire actif comme ceci:

import {TestBed} from '@angular/core/testing';
import {SomeResolver} from './some.resolver';
import {ActivatedRoute, convertToParamMap} from '@angular/router';
import {of} from 'rxjs';

describe('SomeResolver', () => {
  let someResolver: SomeResolver;
  let route: ActivatedRoute;

  TestBed.configureTestingModule({
    providers: [
      {
        provide: ActivatedRoute,
        useValue: {snapshot: {paramMap: convertToParamMap({id: 'one-id'})}}
      },
      SomeResolver
    ]
  });

  beforeEach(() => {
    heroResolver = TestBed.get(HeroResolver);
    route = TestBed.get(ActivatedRoute);
  });

  it('should resolve', (() => {
    someResolver.resolve(route.snapshot);
  }));
});

Vérifiez un exemple plus complexe ici .

5
ismaestro

Je ne sais pas si c'est la meilleure solution, mais vous pouvez vous moquer de l'itinéraire comme ceci:

let route = createSpyObj('Route', ['']);
route.params = {
  val: '1234'
}
5
Janneman96

Si le but est simplement de passer la maquette au résolveur, il n'est pas nécessaire d'utiliser createSpyObj, comme suggéré dans d'autres réponses. De plus, il serait préférable d'ajouter une sécurité de type à la solution:

const mock = <T, P extends keyof T>(obj: Pick<T, P>): T => obj as T;

it('should call foo', () => {
    const route = mock<ActivatedRouteSnapshot, 'params'>({
        params: {
            val: '1234'
        }
    });

    const resolver = createTheResolver();
    const resolverParams = resolver.resolve(route);
    ...
});
1
Valeriy Katkov