Jest ist großartig darin, Importe in Javascript/Typescript zu verspotten, aber es fällt mir sehr schwer, mich an Implementierungsdetails zu erinnern.
Funktionen und Objekte müssen auf unterschiedliche Weise verspottet werden, Standardexporte werden auf subtile Weise anders verspottet als benannte Exporte und Jest funktioniert nicht besonders gut mit Typoskript. Wenn Sie all diese Dinge kombinieren, kann es schwierig sein, den richtigen Ansatz für Ihr Spottszenario zu finden oder gar danach zu suchen.
Ich habe diesen Leitfaden erstellt, um die Frage zu beantworten „Wie verspotte ich meinen Import?“unabhängig davon, um welchen Import es sich handelt. Standard oder benannt, Funktion oder Objekt.
Ich habe alle diese Ansätze mit den folgenden Softwareversionen getestet:
Und mit einer standardmäßigen, minimalen jest.config.js-Datei:
export default { testEnvironment: 'node', transform: { '^.+.tsx?$': ['ts-jest', {}], }, testMatch: ['**/*.test.ts'], };
Weit verbreitete Importe lassen sich in zwei Kategorien einteilen, über die wir uns vielleicht lustig machen möchten:
Wir werden beide nacheinander angehen, beginnend mit den Funktionen.
Aus Modulen exportierte Funktionen können benannt oder standardmäßig sein. Wir werden uns beides ansehen. Erstens:
Dies sollte verwendet werden, um eine benannte exportierte Funktion aus einem Modul zu verspotten, etwa so:
// ./path/to/module.ts export function doSomething(...) { ... }
Es kann so verspottet werden:
import { doSomething } from './path/to/module'; // note: This should be the path to the module from the test file, // NOT from the module that contains the doSomething function itself. jest.mock('./path/to/module', () => ({ doSomething: jest.fn(), })); ... it('should do something', () => { // We need to assert that the function is a jest.Mock // so that typescript will allow us to call mock methods. (doSomething as jest.Mock).mockReturnValue(mockValue); // run your test here expect(doSomething).toHaveBeenCalledTimes(1); // etc. });
Dies sollte verwendet werden, um eine Funktion zu verspotten, die der Standardexport aus einem Modul ist, etwa so:
// ./path/to/module.ts export default function doSomething(...) { ... }
Es wird ähnlich verspottet wie benannte Exporte:
import doSomething from './path/to/module' jest.mock('./path/to/module', () => ({ __esModule: true, default: jest.fn() })) ... it('should do something', () => { (doSomething as jest.Mock).mockResolvedValue(mockData); // Run your test here expect(doSomething).toHaveBeenCalledTimes(5); });
Beim Verspotten eines exportierten Objekts (sei es eine Klasse, ein JSON-Objekt oder etwas anderes) sind einige Variationen zu berücksichtigen.
Wenn Sie nur Eigenschaften verspotten müssen (zum Beispiel eine Konfigurationsdatei), nicht Methoden, dann gehen Sie wie folgt vor:
import config from '../config'; jest.mock('../config', () => ({ __esModule: true, default: { apiKey: '123MockKey', ... }, })); ... it('Should do something', () => { ... });
Und wenn die simulierten Eigenschaften je nach Test variieren müssen:
import config from '../config'; const mockConfig = { apiKey: '123MockKey', ... }; jest.mock('../config', () => ({ __esModule: true, default: mockConfig, })); ... beforeEach(() => { // restore defaults before each test mockConfig.apiKey = '123MockKey'; ... }); it('Should do something', () => { mockConfig.apiKey = 'new value'; // rest of the test }); // more tests
Sehr ähnlich zum Verspotten von Standardexportobjekten:
import { config } from '../config'; const mockConfig = { apiKey: '123MockKey', ... }; jest.mock('../config', () => ({ config: mockConfig, })); // the rest is exactly the same as when mocking a default export object.
Wenn ein Objekt mit Methoden aus einem Modul exportiert wird (benannt oder standardmäßig) und wir die Ausgabe dieser Methoden nachahmen müssen, ist der Ansatz etwas anders.
Eine Klasse gegeben:
// ./path/to/module.ts class ComplicatedThing { // properties, fields, constructor etc. go here getData() { ... } ... } // note: I don't necessarily recommend exporting an instance // of a class like this - purely illustrative for testing purposes. // https://medium.com/@lazlojuly/are-node-js-modules-singletons-764ae97519af export const complicatedThing = new ComplicatedThing(...);
Und um unser exportiertes Objekt zu verspotten:
export default { testEnvironment: 'node', transform: { '^.+.tsx?$': ['ts-jest', {}], }, testMatch: ['**/*.test.ts'], };
Das Verspotten eines Standardexportobjekts ist genau das Gleiche, außer wenn wir das Mock definieren:
// ./path/to/module.ts export function doSomething(...) { ... }
Dies dient dazu, ein Objekt zu verspotten, das nicht direkt in ein Modul importiert wird, das Sie testen, sondern stattdessen als Parameter an eine Klasse/Funktion übergeben wird.
Hinweis: Wenn Sie eine Klasse verspotten, möchten Sie möglicherweise stattdessen eine Schnittstelle und eine Scheinimplementierung davon erstellen, um sie an Ihre Funktion/Klasse zu übergeben. Dadurch ersparen Sie sich die folgenden uneleganten Typenbehauptungs-Spielereien.
import { doSomething } from './path/to/module'; // note: This should be the path to the module from the test file, // NOT from the module that contains the doSomething function itself. jest.mock('./path/to/module', () => ({ doSomething: jest.fn(), })); ... it('should do something', () => { // We need to assert that the function is a jest.Mock // so that typescript will allow us to call mock methods. (doSomething as jest.Mock).mockReturnValue(mockValue); // run your test here expect(doSomething).toHaveBeenCalledTimes(1); // etc. });
// ./path/to/module.ts export default function doSomething(...) { ... }
import doSomething from './path/to/module' jest.mock('./path/to/module', () => ({ __esModule: true, default: jest.fn() })) ... it('should do something', () => { (doSomething as jest.Mock).mockResolvedValue(mockData); // Run your test here expect(doSomething).toHaveBeenCalledTimes(5); });
Ich hoffe, dass dies für Sie und mein zukünftiges Ich nützlich sein wird, wenn ich das nächste Mal Schwierigkeiten habe, mich an die Details zum Verspotten von Importen in Typoskript zu erinnern.
Ich hoffe, dass es alle Ihre einfachen Mock-Bedürfnisse abdecken kann und Ihnen einen Ausgangspunkt für das Mock-Making komplexerer Importe bietet.
Danke fürs Lesen.
Das obige ist der detaillierte Inhalt vonSpott mit Scherz und Typoskript – ein Spickzettel. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!