À l'ère de SPA et de JAMstack, il y a toujours eu une séparation des préoccupations entre les API et le front-end développement. Presque tous les projets JavaScript qui peuvent être découverts dans la nature interagissent avec un service Web ou une API et les utilisent pour des authentifications ou pour obtenir des données liées à l'utilisateur.
Ainsi, chaque fois que vous travaillez sur un projet et que l'API nécessaire est toujours n'a pas été implémentée par l'équipe back-end ou si vous devez tester rapidement une fonctionnalité, vous disposez de certaines des options suivantes:
- Vous pouvez utiliser un proxy vers une version exécutée localement de votre backend réel qui, dans la plupart des cas en tant que développeur front-end, vous ne l'auriez pas fait.
- Vous pouvez commenter la demande réelle et la remplacer par des données factices. (C'est correct, mais pas aussi grand que vous auriez besoin de l'annuler pour accéder à la production et vous pourriez ne pas être en mesure de gérer les états et la latence du réseau.)
Qu'est-ce que le mocking API? ou une simulation d'une API réelle. C'est principalement fait pour intercepter les requêtes qui sont censées être adressées à une API backend réelle, mais ce mocking existe sur votre frontend.
Pourquoi le mocking d'API est-il important?
- Cela permet une très bonne expérience de développement frontal de ne pas dépendre des API de production avant de créer des fonctionnalités.
- Vous pouvez partager l'intégralité de votre frontend et cela fonctionnerait sans dépendre d'une API backend réelle.
Est-ce que Mirage JS?
- Cela permet une très bonne expérience de développement frontal de ne pas dépendre des API de production avant de créer des fonctionnalités.
- Vous pouvez partager l'intégralité de votre frontend et cela fonctionnerait sans dépendre d'une API backend réelle.
Est-ce que Mirage JS?
Mirage JS a été créé il y a 5 ans et était à peu près utilisé dans la communauté Ember avant que Sam Selikoff annonce officiellement sa sortie le 24 janvier 2020 sur Twitter.
Mirage JS résout le problème de tester les API backend sans dépendre de ces API.
Mirage JS est une bibliothèque de simulation d'API pour les frameworks Vue.js, React, Angular et Ember
Qu'est-ce qui fait de Mirage JS un meilleur choix?
Là Il y a eu d'autres options pour le mocking API (comme les intercepteurs Axios, le serveur JSON de Typicode etc.) mais ce qui me semble assez intéressant à propos de Mirage, c'est qu'il ne gêne pas votre processus de développement (comme vous le verriez quand nous l'avons installé avec Vue dans un peu). Il est léger et pourtant puissant.
Il est livré avec une batterie incluse qui vous permet de reproduire des scénarios de consommation d'API de production réelle, comme la simulation d'un réseau lent avec son option de synchronisation .
Mise en route Avec Mirage JS et Vue.js
Alors maintenant que vous savez ce qu'est Mirage JS et pourquoi il est important pour votre flux de travail de développement frontal, examinons la configuration avec le framework Web progressif: Vue.js.
Création d'un projet Vue verte (installation propre)
À l'aide de la CLI CLI créez un nouveau projet Vue.js en accédant au répertoire dans lequel vous souhaitez créer le projet. en cours d'exécution (dans votre terminal):
vue create miragejs-demo-vue
La commande ci-dessus créerait un nouveau projet Vue que vous pouvez maintenant cd
dans et exécuter soit service de fil
soit npm run serve
.
. #Installation de Mirage JS
Maintenant, installons Mirage JS en tant que dépendance de développement dans notre projet Vue.js en exécutant la commande suivante:
yarn add -D miragejs
Ou si vous utilisez NPM, exécutez ceci:
npm install --save-dev miragejs
Et c'est tout! Mirage JS est maintenant installé dans notre projet Vue.js .
Mock Out Something
Avec Mirage JS installé, voyons comment nous le configurons pour parler à Vue et simuler un todos de base ( une API qui renvoie une liste de todos).
Définissez votre serveur
Pour commencer, nous devons créer un fichier server.js dans le répertoire / src
de notre projet Vue.js . Après cela, ajoutez ce qui suit:
import {Server, Model} from 'miragejs'
fonction d'exportation makeServer ({environnement = "développement"} = {}) {
laisser serveur = nouveau serveur ({
environnement,
des modèles: {
todo: modèle,
},
graines (serveur) {
server.create ("todo", {content: "Learn Mirage JS"})
server.create ("todo", {content: "Integrate With Vue.js"})
},
routes () {
this.namespace = "api"
this.get ("/ todos", schéma => {
renvoie schema.todos.all ()
})
},
})
serveur de retour
}
Explication du code
Premièrement, le fichier server.js est la façon dont vous configurez Mirage JS pour créer une nouvelle instance de son faux serveur (faux) qui interceptera tous les appels d'API que vous effectuez dans votre application correspondant aux itinéraires que vous définissez.
Maintenant, je suis d'accord que ce qui précède peut être écrasant au début, mais regardons de plus près ce qui se passe ici:
import {Server, Model} from 'miragejs'
À partir de l'extrait de code ci-dessus, nous importons Server
et Model
de miragejs
.
-
Server
Ceci est une classe exposé par Mirage pour nous aider à instancier une nouvelle instance d'un serveur Mirage JS pour «servir» de faux serveur. -
Model
Une autre classe exposée par Mirage pour aider à créer des modèles (un modèle détermine la structure d'une entrée de base de données Mirage JS) propulsé par l'ORM de Mirage.
fonction d'exportation makeServer ({environment = "development"} = {}) {}
Ce qui précède exporte essentiellement une fonction appelée makeServer
à partir du src / server.js
. Vous pouvez également noter que nous passons un paramètre d'environnement et que nous définissons le mode d'environnement de Mirage sur développement
(vous nous verriez passer un environnement de test plus loin dans cet article).
The Body Of makeServer
Nous faisons maintenant deux ou trois choses dans le corps makeServer
. Jetons un coup d'œil:
let server = new Server ({})
Nous instancions une nouvelle instance de la classe Server et lui transmettons une option de configuration. Le contenu des options de configuration permet de configurer mirage:
{
environnement,
des modèles: {
todo: modèle,
},
graines (serveur) {
server.create ("todo", {content: "Learn Mirage JS"})
server.create ("todo", {content: "Integrate With Vue.js"})
},
routes () {
this.namespace = "api"
this.get ("/ todos", schéma => {
renvoie schema.todos.all ()
})
},
}
Tout d'abord, nous passons le paramètre d'environnement
que nous avons initialisé dans la définition de la fonction.
modèles: {
todo: modèle,
},
L'option suivante qui est les modèles
prend un objet des différents modèles que nous voulons que Mirage moque.
Dans ce qui précède, nous voulons simplement un modèle todo que nous instancions à partir du modèle
graines (serveur) {
server.create ("todo", {content: "Learn Mirage JS"})
server.create ("todo", {content: "Integrate With Vue.js"})
},
L'option suivante est la méthode des graines qui prend un paramètre appelé serveur
. La méthode des graines permet de créer des graines (les graines sont des données initiales ou une entrée dans la base de données de Mirage) pour nos modèles. Dans notre cas, pour créer les graines du modèle de tâches, nous faisons:
server.create ("todo", {content: "Learn Mirage JS"})
server.create ("todo", {content: "Integrate With Vue.js"})
donc le serveur a une méthode create qui attend comme premier argument une chaîne qui correspond au nom du modèle, puis un objet qui contiendra les propriétés ou les attributs d'une graine particulière.
routes () {
this.namespace = "api"
this.get ("/ todos", schéma => {
renvoie schema.todos.all ()
})
},
enfin, nous avons la méthode des routes qui définit les différentes routes (les routes sont nos noeuds finaux d'API). Mirage JS va se moquer. Regardons le corps de la méthode:
this.namespace = "api"
cette ligne définit l'espace de noms pour toutes les routes, ce qui signifie que notre route todo est désormais accessible à partir de /api/todos.[19659037[thth..get("/todos ", schema => {
renvoie schema.todos.all ()
})
Ce qui précède crée un itinéraire get et son gestionnaire utilise la méthode this.get ()
. La méthode get ()
attend la route c.-à-d. «/ Todos» et une fonction de gestionnaire qui utilise le schéma
comme argument. L'objet de schéma est la façon dont vous interagissez avec l'ORM de Mirage qui est alimenté par la base de données en mémoire Mirage JS.
Enfin:
return schema.todos.all ()
Nous retournons une liste de tous nos todos, en utilisant l'objet de schéma rendu possible par l'ORM de Mirage.
src / main.js
Nous avons donc fini de configurer src / server.js
mais Vue ne le sait pas (du moins pas encore). Importons-le donc dans notre fichier main.js comme ceci:
importez {makeServer} de "./server"
Ensuite, nous appelons la fonction makeServer
comme ceci:
if (process.env.NODE_ENV === "development") {
makeServer ()
}
Ce qui précède si
conditionnel est un garde pour s'assurer que mirage ne fonctionne que pendant le développement.
Configuration terminée!
Nous avons maintenant configuré Miragejs avec Vue. Voyons cela en action. Dans notre fichier App.vue nous effacerions le contenu et le remplacerions par l'extrait de code ci-dessous:
Si vous êtes familier avec Vue.js, ce qui précède ne serait rien de nouveau mais pour être complet, ce que nous faisons est de faire une demande d'API en utilisant fetch
lorsque notre App. vue
le composant est créé, puis nous passons les données retournées au tableau todos dans notre état de composant. Ensuite, nous utilisons un v-for pour itérer le tableau de todos et afficher la propriété de contenu de chaque tâche.
Où est la partie Mirage JS?
Si vous remarquez, dans notre composant App.vue, nous n'avons pas '' t faire quelque chose de spécifique à Mirage, nous faisons juste un appel API comme nous le ferions normalement. Cette fonctionnalité de Mirage est vraiment géniale pour la cause DX sous le capot, Mirage intercepterait toutes les demandes qui correspondent à l'une des routes définies dans src / server.js pendant que vous êtes en développement.
C'est assez pratique car aucun travail ne serait nécessaire de votre part pour passer à un serveur de production réel lorsque vous êtes dans un environnement de production à condition que les routes correspondent à vos points de terminaison de l'API de production.
Redémarrez donc votre serveur de développement Vue via yarn serve
pour tester Mirage JS.
Vous devriez voir une liste de deux todos. Une chose que vous trouverez assez intéressante est que nous n'avons pas eu besoin d'exécuter une commande de terminal pour démarrer Mirage car elle supprime cette surcharge en s'exécutant dans le cadre de votre application Vue.js.
Mirage JS et vue test-utils
Si vous utilisez déjà Vue Test-utils dans votre application Vue, il serait intéressant de savoir que Mirage peut facilement travailler avec lui pour se moquer des demandes du réseau. Voyons un exemple configuré à l'aide de notre application todos.
Nous utiliserions Jest pour nos tests unitaires. Donc, si vous suivez, vous pouvez à peu près utiliser l'interface CLI pour installer le plugin @ vue / unit-jest
comme ceci:
vue add @ vue / unit-jest
Ce qui précède installera @ vue / cli-plugin-unit-jest
et @ vue / test-utils
les dépendances de développement tout en créant également un répertoire tests
. et un fichier jest.config.js . Il ajoutera également la commande suivante dans notre section package.json scripts
(assez soignée):
"test: unit": "vue-cli-service test: unit"
Essayons!
Nous mettrons à jour notre App.vue pour qu'il ressemble à ceci:
Rien de vraiment épique ne se passe dans l'extrait ci-dessus; nous sommes juste en train de structurer pour permettre les tests de réseau que nous implémenterions avec notre test unitaire.
Bien que Vue CLI ait déjà ajouté un dossier / tests
pour nous, je trouve que c'est une bien meilleure expérience lorsque mes tests sont placés à proximité des composants qu'ils testent. Créez donc un dossier / __ tests __
dans src /
et créez un fichier App.spec.js à l'intérieur. (C'est également l'approche recommandée par Jest.)
// src / __ tests __ / App.spec.js
importer {mount} depuis "@ vue / test-utils"
importer {makeServer} depuis "../server"
importer l'application depuis "../App.vue"
laisser le serveur
beforeEach (() => {
server = makeServer ({environnement: "test"})
})
afterEach (() => {
server.shutdown ()
})
Donc, pour configurer nos tests unitaires, nous importons la méthode mount
de @ vue / test-utils
en important le serveur Miragejs que nous avons créé plus tôt et enfin en important le Composant App.vue
.
Ensuite, nous utilisons la fonction de cycle de vie beforeEach
pour démarrer le serveur Mirage JS tout en passant dans l'environnement de test. (N'oubliez pas, nous définissons par défaut l'environnement comme étant développement
.)
Enfin, nous arrêtons le serveur à l'aide de server.shutdown
dans le après chaque
méthode de cycle de vie.
Nos tests
Maintenant, étoffons notre test (nous adopterions la section de démarrage rapide des documents Mirage js . Donc, votre App.spec.js ressemblerait finalement à ceci:
// src / __ tests __ / App.spec.js
importer {mount} depuis "@ vue / test-utils"
importer {makeServer} depuis "./server"
importer l'application depuis "./App.vue"
laisser le serveur
beforeEach (() => {
server = makeServer ({environnement: "test"})
})
it ("affiche les todos de notre serveur", async () => {
server.create ("todo", {id: 1, content: "Learn Mirage JS"})
server.create ("todo", {id: 2, content: "Integrate with Vue.js"})
const wrapper = mount (App)
// attendons que notre composant vue termine le chargement des données
// nous savons que c'est fait lorsque le data-testid entre dans le dom.
wait waitFor (wrapper, '[data-testid="todo-1"]')
wait waitFor (wrapper, '[data-testid="todo-2"]')
expect (wrapper.find ('[data-testid="todo-1"]'). text ()). toBe ("Learn Mirage JS")
expect (wrapper.find ('[data-testid="todo-2"]'). text ()). toBe ("Intégrer avec Vue.js")
})
it ("affiche un message s'il n'y a pas de tâche", async () => {
// Ne créez aucun todos
const wrapper = mount (App)
wait waitFor (wrapper, '[data-testid="no-todos"]')
expect (wrapper.find ('[data-testid="no-todos"]'). text ()). toBe ("No todos!")
})
// Cette méthode d'assistance renvoie une promesse qui résout
// une fois que le sélecteur entre dans le dom du wrapper.
const waitFor = fonction (wrapper, sélecteur) {
retourner une nouvelle promesse (résoudre => {
const timer = setInterval (() => {
const todoEl = wrapper.findAll (sélecteur)
if (todoEl.length> 0) {
clearInterval (timer)
résoudre()
}
}, 100)
})
}
afterEach (() => {
server.shutdown ()
})
Note : Nous utilisons ici un assistant (tel que défini dans les documents Mirage JS). Il renvoie une promesse qui nous permet de savoir quand les éléments que nous testons sont déjà dans le DOM.
Maintenant, lancez test de fil: unité
.
Tous vos tests devraient réussir à ce stade.
Test de différents états de serveur avec Mirage JS
Nous pouvons modifier notre serveur Mirage JS pour tester différents états de serveur. Voyons comment.
// src / __ tests __ / App.spec.js
importer {Response} depuis "miragejs"
D'abord, nous importons la classe Response
de Mirage, puis nous créons un nouveau scénario de test comme ceci:
it ("gère les réponses d'erreur du serveur", async () => {
// Remplace le gestionnaire de route de Mirage pour / todos, juste pour ce test
server.get ("/ todos", () => {
retourner une nouvelle réponse (
500,
{},
{
erreur: "La base de données fait une pause.",
}
)
})
const wrapper = mount (App)
wait waitFor (wrapper, '[data-testid="server-error"]')
expect (wrapper.find ('[data-testid="server-error"]'). text ()). toBe (
"La base de données fait une pause."
)
})
Exécutez votre test et tout devrait réussir.
Conclusion
Cet article avait pour but de vous présenter Mirage JS et de vous montrer comment il permet une meilleure expérience de développement front-end. Nous avons vu le problème que Mirage JS a créé pour résoudre (créer un front-end prêt pour la production sans aucune API backend réelle) et comment le configurer avec Vue.js.
Bien que cet article ait effacé la surface de ce que Mirage JS peut faire, Je pense que cela suffit pour vous aider à démarrer.
- Vous pouvez parcourir les documents et rejoindre le serveur Mirage JS discord .
- Le référentiel de prise en charge de cet article est disponible sur GitHub .
Références
Source link