2015-10-02 18 views

Antwort

53

Figured es mit Hilfe aus dieser: https://groups.google.com/forum/#!topic/jestjs/9EPhuNWVYTg

Setup-Datei mit folgendem Inhalt:

var localStorageMock = (function() { 
 
    var store = {}; 
 
    return { 
 
    getItem: function(key) { 
 
     return store[key]; 
 
    }, 
 
    setItem: function(key, value) { 
 
     store[key] = value.toString(); 
 
    }, 
 
    clear: function() { 
 
     store = {}; 
 
    }, 
 
    removeItem: function(key) { 
 
     delete store[key]; 
 
    } 
 
    }; 
 
})(); 
 
Object.defineProperty(window, 'localStorage', { value: localStorageMock });

Sie dann die folgende Zeile in package.json hinzufügen unter Ihr Jest konfiguriert

"setupTestFrameworkScriptFile":"PATH_TO_YOUR_FILE",

+5

Offenbar mit einem der Updates der Name dieser Parameter geändert und jetzt ist es "setupTestFrameworkScriptFile" –

+1

' "Setupfiles" genannt: [...]' funktioniert auch. Mit der Array-Option können Mocks in separate Dateien aufgeteilt werden. Zum Beispiel: '" setupFiles ": [" /__ mocks __/localStorageMock.js "]' – Stiggler

+3

Der Rückgabewert von 'getItem' unterscheidet sich geringfügig von dem, was von einem Browser zurückgegeben würde, wenn die keine Daten für einen bestimmten Schlüssel festgelegt sind. ruft 'getItem (" foo ")' auf, wenn es nicht gesetzt ist, wird zum Beispiel "null" in einem Browser zurückgegeben, aber "undefiniert" durch diesen Mock - dies hat einen meiner Tests zum Scheitern gebracht.Eine einfache Lösung für mich war, 'store [key] || zurückzugeben null 'in der' getItem'-Funktion –

58

Große Lösung von @chiedo

Allerdings verwenden wir ES2015 Syntax und ich spürte, es war ein wenig sauberes es auf diese Weise zu schreiben.

class LocalStorageMock { 
 
    constructor() { 
 
    this.store = {}; 
 
    } 
 

 
    clear() { 
 
    this.store = {}; 
 
    } 
 

 
    getItem(key) { 
 
    return this.store[key] || null; 
 
    } 
 

 
    setItem(key, value) { 
 
    this.store[key] = value.toString(); 
 
    } 
 

 
    removeItem(key) { 
 
    delete this.store[key]; 
 
    } 
 
}; 
 

 
global.localStorage = new LocalStorageMock;

+3

Sollte wahrscheinlich' value + '' 'in der Setter, um Null undefined Werte richtig zu behandeln – menehune23

9

Eine bessere Alternative, die undefined Werte Griffe (nicht toString() hat) und gibt null, wenn der Wert nicht existiert. Getestet dies mit react v15, redux und redux-auth-wrapper

class LocalStorageMock { 
    constructor() { 
    this.store = {} 
    } 

    clear() { 
    this.store = {} 
    } 

    getItem(key) { 
    return this.store[key] || null 
    } 

    setItem(key, value) { 
    this.store[key] = value 
    } 

    removeItem(key) { 
    delete this.store[key] 
    } 
} 

global.localStorage = new LocalStorageMock 
+0

Dank Alexis Tyler für die Idee,' removeItem' hinzuzufügen: https: //developer.mozilla .org/de-DE/docs/Web/API/Speicher/removeItem – Dmitriy

+0

Glauben Sie, dass null und undefined zu "null" und "undefined" führen müssen (literale Zeichenfolgen) – menehune23

0

Riffed einige andere Antworten hier, um es für ein Projekt mit Typescript zu lösen. Ich habe ein LocalStorageMock wie folgt aus:

export class LocalStorageMock { 

    private store = {} 

    clear() { 
     this.store = {} 
    } 

    getItem(key: string) { 
     return this.store[key] || null 
    } 

    setItem(key: string, value: string) { 
     this.store[key] = value 
    } 

    removeItem(key: string) { 
     delete this.store[key] 
    } 
} 

Dann habe ich eine LocalStorageWrapper Klasse, die ich für alle Zugriff auf einen lokalen Speicher in der App verwenden, anstatt direkt die globale lokale Speichervariable zugreifen. Es wurde leicht gemacht, den Mock im Wrapper für Tests zu setzen.

6

Wenn Sie create-react-app verwenden, gibt es eine einfachere und einfachere Lösung, die in der documentation erläutert wird.

erstellen src/setupTests.js und setzen diese in ihm:

const localStorageMock = { 
    getItem: jest.fn(), 
    setItem: jest.fn(), 
    clear: jest.fn() 
}; 
global.localStorage = localStorageMock; 
+0

Hi c4k! Könnten Sie bitte ein Beispiel geben, wie Sie das in Ihren Tests verwenden würden? – Dimo

+0

Was meinst du? Sie müssen nichts in Ihren Tests initialisieren, es macht nur die 'localStorage', die Sie in Ihrem Code verwenden, frei. (wenn Sie 'create-react-app' und alle automatischen Skripte verwenden, die es natürlich bereitstellt) – c4k

Verwandte Themen