IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Angular Discussion :

Mock objet Javascript externe


Sujet :

Angular

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2017
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2017
    Messages : 2
    Par défaut Mock objet Javascript externe
    Bonsoir à tous,

    Après plus de 4 jours de tentatives diverses, je me décide enfin à demander de l'aide.

    J'ai une application Angular dont le seul but est de générer des WebElements (via @angular/elements) donc je n'ai plus d'index.html, pas de app.component, etc.

    Ces éléments sont utilisés dans une application .NET Mvc qui possède deux types de choses que j'essaie de "mocker" dans mes tests unitaire:

    1 - Des librairies externes

    Par exemple JQuery, lodash, etc.
    Je n'ajoute pas ces librairies à mon application Angular car les fichiers sources sont déjà fournit par la vue MVC qui appelle mes composants Angular, ça ferait double emploi.

    2 - Framework client "foo"

    Dans la vue MVC, l'application .Net MVC va créer un objet que l'on va nommé "foo". Ce n'est pas un module ES6, il est créé avec des options provenant du serveur via la session utilisateur (géré en .Net donc):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const foo = new Foo({ someOptionsGeneratedFromServerSide});
    Le problème vient du fait que ces deux choses sont utilisés par mes composants Angular. Par exemple, un composant va pouvoir utiliser la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    foo.displayAlert('avec un message');
    La solution pour faire coïncider les deux a été de référencer le fichier de définitions de l'objet foo comme suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // tslint:disable-next-line: max-line-length no-reference
    /// <reference path='path/to/the/definition.d.ts' />
    Je sais que c'est peu orthodoxe comme méthode mais le principe ne me parait pas fou: créer des composants réutilisable (WebElements) via Angular et s'en servir autre part. Vu que c'est dans une approche purement corporate, ces éléments utilisent les ressources interne de l'application principale (.NET Mvc): objet foo, JQuery, lodash, fichiers de styles globaux, etc.

    L'application Angular marche très bien jusqu'à ce que j'essaie de faire mes tests unitaire.
    Pour information: l'application ne peut marcher toute seule: ng serve est devenu inutile dans mon cas: c'est la vue MVC qui importe tout ce qu'il faut.

    Voici un exemple de test unitaire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    it('should render title', () => {
      const fixture = TestBed.createComponent(AppComponent);
      fixture.detectChanges();
      const compiled = fixture.nativeElement;
      expect(compiled.querySelector('.content span').textContent).toContain('ng-jest app is running!');
    });
    Pour cette partie de composant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ngOnInit() {
      foo.displayAlert('With a message');
    }
    Cela ne marche pas avec le message d'erreur suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    AppComponent › should render title
    ReferenceError: foo is not defined
    Ce qui n'est pas surprenant en soi: le test-runner (Karma dans ce cas) va lancer un browser qui va lancer l'application.
    Or, l'application ne peut marcher sans les ressources apportées par la vue MVC.

    J'ai essayé de "mocker" l'objet avant le test:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    let foo: any;
      beforeEach(async(() => {
        TestBed.configureTestingModule({
          imports: [
            RouterTestingModule
          ],
          declarations: [
            AppComponent
          ],
        }).compileComponents();
        foo = {
          displayAlert: Function
        };
      }));
    Ce qui n'a pas marché, selon moi car cette variable n'est pas fournit au composant mais uniquement dans le scope du test unitaire. Peut-être la solution serait d'injecter cette variable au composant ?
    J'ai essayé beaucoup de choses dans le x.spec.ts sur cet objet sans résultats probant.

    J'ai créé une autre application Angular avec un index.html qui inclut manuellement toutes les ressources de la vue MVC mais cela n'a pas fonctionné non plus. Je pense que je dois également faire la même chose dans le test-runner Karma: cela marcherait je pense pour les librairies externes mais pas pour l'objet foo qui, comme dit plus haut, s'initialise avec des données serveur.

    Les librairies externes telles que JQuery & lodash ne devraient pas, selon moi, être incluses dans le projet Angular: la vue MVC s'en charge et niveau taille des fichiers finaux / maintenabilité / etc. c'est mieux.
    J'ai essayé de les mettre en tant que "devDependencies" dans mon gestionnaire de packet afin qu'elles ne soient pas dans les fichiers finaux: en vain.

    Mon but est de de pouvoir "mocker" mon objet foo ainsi que mes librairies externes afin de pouvoir enfin avoir la possibilité de faire mes unit tests.

    Dernière information: j'ai essayé avec (Jest) & sans (Karma) un "headless browser" pour les tests: même résultat.

    J'aimerai vraiment arriver à faire marcher cette problématique. Je fais partie d'une boîte qui considère les tests unitaire comme étant une perte de temps et ne veut pas entendre parler de TDD. J'aimerai profiter de ce projet pour leur prouver l'utilité de ces notions (et surtout, le faire pour moi).

    Votre aide me serait plus que précieuse. Je commence à réellement désespéré.

    Merci d'avance!
    Etienne.

  2. #2
    Candidat au Club
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2017
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2017
    Messages : 2
    Par défaut Solution
    Bonsoir à tous,

    Pour ceux qui voudraient la solution à mon problème:

    Il est tout à fait possible de mocker l'objet "foo". Il est dans le scope global et doit donc être déclaré comme suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (window as any).foo= { displayAlert: () => {}};
    Merci à tous ceux qui ont pris le temps de lire mon problème

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [POO] contenu d'un objet javascript
    Par wtfu dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 10/08/2006, 11h12
  2. [POO] Comment acceder a un objet javascript instancie dans une page mere
    Par herbert dans le forum Général JavaScript
    Réponses: 11
    Dernier message: 20/07/2006, 19h34
  3. Données JavaScript externe ?
    Par dunbar dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 14/07/2006, 13h07
  4. fichier javascript externe
    Par Dave Lopeur dans le forum Général JavaScript
    Réponses: 10
    Dernier message: 15/05/2006, 11h30
  5. [POO] objet javascript et html
    Par jakouz dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 20/04/2006, 17h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo