5
votes

Dans les tests unitaires Jasmine: impossible de résoudre tous les paramètres de TestFormInputComponentBase

Je suis nouveau dans l'application Angular de test unitaire et j'essaye de tester mon premier composant. En fait, j'essaie de tester une classe de base abstraite qui est utilisée par les composants réels, j'ai donc créé un composant simple dans mes spécifications basé sur cela et je l'utilise pour le tester. Mais il y a une dépendance à gérer ( Injector ) et je ne l'écrase pas correctement car lorsque j'essaye d'exécuter le test, j'obtiens cette erreur:

Impossible de tout résoudre paramètres pour TestFormInputComponentBase

Mais je ne suis pas sûr de ce que j'ai manqué? Voici la spécification:

    Error: StaticInjectorError(DynamicTestModule)[LanguageService]: 
    StaticInjectorError(Platform: core)[LanguageService]: 
    NullInjectorError: No provider for LanguageService!

Voici la classe GenFormInputComponentBase que j'essaie de tester:

@Component({})
class TestFormInputComponent extends GenesysFormInputComponentBase {
    constructor(injector: Injector) {
        super(injector);
    }
}

describe('GenesysFormInputComponentBase (class only)', () => {
    let component: TestFormInputComponent;

    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [
                TestFormInputComponent,
                {
                    provide: Injector,
                    useObject: {}
                }
            ]
        });

        component = TestBed.get(TestFormInputComponent);
    });

    it('should validate required field inputs on ngOnInit', () => {
        expect(() => component.ngOnInit()).toThrowError(
            `Missing 'field' input in GenesysFormInputComponentBase.`
        );
    });
});


1 commentaires

Quoi que je fasse, je ne peux pas simuler la dépendance de TestFormInputComponentBase . C'est comme si les fournisseurs que j'ajoute étaient ignorés. J'utilise l'exemple de code fourni par Angular pour cela, mais cela ne fonctionne pas. angular.io/guide/testing#component-with-a-dependency


3 Réponses :


0
votes

Vous voulez tester GenFormInputComponentBase alors pourquoi ne pas le tester sans TestFormInputComponent

        providers: [
          LanguageService,
          {
                provide: Injector,
                useValue: {}
          }
        ]

Ou avec les fournisseurs LanguageService ressemble à: p>

   TestBed.configureTestingModule({
        declarations: [
            GenFormInputComponentBase,
        ],
        providers: [
          {
                provide: LanguageService,
                useValue: {}
          }
        ]
    });


0 commentaires

2
votes

Il existe de nombreuses façons différentes d'aborder cela, mais vous pouvez le stuber directement dans l'appel à super () dans votre TestFormInputComponent, comme ceci:

it('should validate required `field` input on ngOnInit', () => {
    expect(() => baseClass.ngOnInit()).toThrowError(
        `Missing 'field' input in AppFormInputComponentBase`
    );
});

En outre, vous devez modifier la façon dont vous testez une erreur générée dans une fonction. Voir une discussion détaillée ici . Comme vous pouvez le voir dans cette discussion, il existe de nombreuses façons de le faire également, en voici une simple utilisant une fonction anonyme:

class TestFormInputComponent extends GenFormInputComponentBase {
      constructor() {
          let injectorStub: Injector = { get() { return null } };
          super(injectorStub);
    }
}

Voici un StackBlitz qui le montre fonctionnement. J'ai également ajouté un autre test pour montrer une initialisation sans erreur.

J'espère que cela vous aidera!


4 commentaires

Je vois dans votre mise à jour de la question d'origine que vous aviez déjà commencé à utiliser une fonction anonyme pour tester l'erreur. :)


Oui, je ne l'ai pas vu au départ parce que le test n'est pas allé aussi loin dans l'exécution.


Peut-il être supprimé via le TestBed ? Dans ce cas particulier, c'est très bien car j'ai besoin du composant factice de toute façon pour tester la classe abstraite. Mais j'ai aussi plusieurs composants réels qui étendent ces classes de base abstraites. Ne serait pas en mesure de les tester directement, devrait les étendre avec un composant factice similaire. C'est utilisable s'il n'y a pas de meilleure option mais semble que cela devrait fonctionner d'une manière ou d'une autre directement avec TestBed.configureTestingModule


Avec la façon dont vous utilisez inject dans GenComponentBase , vous devez prendre en main l'injection réelle afin de la simuler à cause de l'injection de dépendances hiérarchiques. Détails ici . Sans se moquer avant de l'envoyer, IDK comment vous obtiendrez le bon à ce niveau. Cela prendra quelqu'un avec plus d'expérience que moi pour comprendre. :)



1
votes

Oui, écrire un constructor () {} et appeler super () dans le constructeur résout ce problème si votre classe n'a pas @injectable () décorateur.

 constructor() {
    super();
}


0 commentaires