2017-12-31 149 views
1

Ich möchte einige Komponententests für eine React Native/TypScript-App schreiben. Das Problem ist, dass einige der Bibliotheken nicht in der Entwicklungsumgebung ausgeführt werden, wie die 'AsyncStorage' oder 'react-native-sqlite-2'.Nicht-Komponente Unit-Tests in React Native

Das einzige, was ich auf der Jest-Website gefunden habe, ist Spott, aber das ist nur eine Möglichkeit, die UI-Tests zu entkoppeln.

Ich dachte daran, eine node.js-Bibliothek zu verwenden, um diese Bibliotheken zu simulieren und die richtigen zu laden, abhängig von der Umgebung.

Etwas wie:

if(isDevelopment) { 
    SQLiteDatabase = require("./sqlite_database_node").SQLiteDatabaseNode; 
} 
else { 
    SQLiteDatabase = require("./sqlite_database_rn").SQLiteDatabaseRN; 
} 

Ist dies der richtige Weg, um dieses Problem zu gehen? Wenn ja, wie importiere/benötige ich, damit es funktioniert? Wenn nein, was ist der beste Weg?

Antwort

3

Wenn Sie Jest oder einen anderen Komponententest ausführen. Die Tests werden in der Knotenumgebung ausgeführt. Wenn Sie also versuchen, auf ein Modul zuzugreifen, das eine native Komponente/Bibliothek aufweist (z. B. Async Storage oder SQLite), wird der Code im Test-env unterbrochen.

Um dieses Problem zu lösen, kam Jest mit Modul-Mocks auf. Also, was ich in meinen Projekten mache, ist das für jedes node_module, das ich benutze, welches intern ein natives Modul benutzt .. ich erstelle einen globalen Mock dafür.

tun, dass Sie einfach einen Ordner __mocks__ im Stammverzeichnis lässt wie so bei

__mocks__/react-native-firebase.js

module.exports = { 
    crash:() => ({ 
    setCrashCollectionEnabled: jest.fn() 
    }), 
    auth:() => ({ 
    signInAnonymously: jest.fn() 
    }), 
    database:() => ({ 
    ref:() => ({ 
     on: jest.fn() 
    }) 
    }), 
    config:() => ({ 
    fetch: jest.fn(), 
    setDefaults: jest.fn(), 
    getValue: jest.fn() 
    }), 
    messaging: jest.fn(() => ({ 
    requestPermissions: jest.fn(), 
    subscribeToTopic: jest.fn(), 
    getToken: jest.fn(Promise.resolve), 
    onMessage: jest.fn(), 
    getInitialNotification: jest.fn(Promise.resolve), 
    onTokenRefresh: jest.fn() 
    })) 
}; 

oder Sie vielleicht __mocks__/react-native-device-info

aussehen

. 
├── README.md 
├── __mocks__ 
│   ├── base-64.js 
│   ├── react-native-animatable.js 
│   ├── react-native-config.js 
│   ├── react-native-device-info.js 
│   ├── react-native-fetch-blob.js 
│   ├── react-native-firebase.js 
│   ├── react-native-google-analytics-bridge.js 
│   ├── react-native-map-markerclustering.js 
│   ├── react-native-maps.js 
│   ├── react-native-simple-download-manager.js 
│   ├── react-native-simple-toast.js 
│   ├── react-native-splash-screen.js 
│   ├── react-native-testfairy.js 
│   ├── react-native-version-number.js 
│   └── react-native.js 
├── __tests__ 
│   └── index.test.js 
├── app 
│   ├── App.container.js 
│   ├── __tests__ 
│   ├── assets 
│   ├── components 
│   ├── config 
│   ├── index.js 
│   ├── language 
│   ├── pages 
│   ├── redux 
│   ├── routes 
│   ├── themes 
│   └── utils 
├── app.json 
├── circle.yml 
├── index.js 
├── package.json 
└── yarn.lock 

Und als Beispiel erstellen

const mockmod = jest.genMockFromModule('react-native-device-info'); module.exports = mockmod;

der Punkt ist .. während des Tests env Scherz automatisch diese Dateien verwenden würde, wenn u require('react-native-device-info')

Als Ergebnis in Test env tun u eine verspottete Modul laufen haben und in der App env haben Sie die aktuelles Knotenmodul.