J'essaie de simuler un appel à un service, mais je me bats avec le message suivant: La fabrique de modules de jest.mock()
n'est pas autorisée à référencer des variables hors de portée =.
J'utilise babel avec la syntaxe ES6, la plaisanterie et l'enzyme.
J'ai un composant simple appelé Vocabulary
qui obtient une liste de VocabularyEntry
- objets à partir d'un vocabularyService
et le rend.
import React from 'react';
import vocabularyService from '../services/vocabularyService';
export default class Vocabulary extends React.Component {
render() {
let rows = vocabularyService.vocabulary.map((v, i) => <tr key={i}>
<td>{v.src}</td>
<td>{v.target}</td>
</tr>
);
// render rows
}
}
Le vocabularyServise
est très simple:
import {VocabularyEntry} from '../model/VocabularyEntry';
class VocabularyService {
constructor() {
this.vocabulary = [new VocabularyEntry("a", "b")];
}
}
export default new VocabularyService();`
Maintenant, je veux me moquer du vocabularyService
dans un test:
import {shallow} from 'enzyme';
import React from 'react';
import Vocabulary from "../../../src/components/Vocabulary ";
import {VocabularyEntry} from '../../../src/model/VocabularyEntry'
jest.mock('../../../src/services/vocabularyService', () => ({
vocabulary: [new VocabularyEntry("a", "a1")]
}));
describe("Vocabulary tests", () => {
test("renders the vocabulary", () => {
let $component = shallow(<Vocabulary/>);
// expect something
});
});
L'exécution du test provoque une erreur: Vocabulary.spec.js: babel-plugin-jest-hoist: la fabrique de modules de jest.mock()
n'est pas autorisée à référencer des variables hors de portée. Accès variable non valide: VocabularyEntry.
Pour autant que je ne l'ai pas compris, je ne peux pas utiliser le VocabularyEntry car il n'est pas déclaré (car jest déplace la définition fictive en haut du fichier).
Quelqu'un peut-il expliquer comment je peux résoudre ce problème? J'ai vu des solutions qui nécessitaient les références dans le faux appel mais je ne comprends pas comment je peux le faire avec un fichier de classe.
Le problème est que tous les jest.mock
sera hissé en haut du bloc de code réel au moment de la compilation, qui est dans ce cas le haut du fichier. À ce stade, VocabularyEntry
n'est pas importé. Vous pouvez soit placer le mock
dans un bloc beforeAll
dans votre test, soit utiliser jest.mock
comme ça:
import {shallow} from 'enzyme';
import React from 'react';
import Vocabulary from "../../../src/components/Vocabulary ";
import {VocabularyEntry} from '../../../src/model/VocabularyEntry'
import vocabularyService from '../../../src/services/vocabularyService'
jest.mock('../../../src/services/vocabularyService', () => jest.fn())
vocabularyService.mockImplementation(() => ({
vocabulary: [new VocabularyEntry("a", "a1")]
}))
Cela se moquera d'abord du module avec un simple espion et après que tout le matériel soit importé, il définira la véritable implémentation de la maquette.
Si vous obtenez une erreur similaire lors de la mise à niveau vers une version plus récente de Jest [19 à 21 dans mon cas], vous pouvez essayer de modifier jest.mock
à jest.doMock
.
Trouvé ceci ici - https://github.com/facebook/jest/commit/6a8c7fb874790ded06f4790fdb33d8416a7284c8
C'est ainsi que je le résoudrais pour votre code.
Vous devez stocker votre composant simulé dans une variable avec un nom préfixé par "simulé". Cette solution est basée sur la note à la fin du message d'erreur que je recevais.
Remarque: Il s'agit d'une précaution pour se prémunir contre les variables factices non initialisées. S'il est garanti que la maquette est requise paresseusement, les noms de variables précédés de
mock
sont autorisés.
import {shallow} from 'enzyme';
import React from 'react';
import Vocabulary from "../../../src/components/Vocabulary ";
import {VocabularyEntry} from '../../../src/model/VocabularyEntry'
const mockVocabulary = () => new VocabularyEntry("a", "a1");
jest.mock('../../../src/services/vocabularyService', () => ({
default: mockVocabulary
}));
describe("Vocabulary tests", () => {
test("renders the vocabulary", () => {
let $component = shallow(<Vocabulary/>);
// expect something
});