Reputation: 3209
Jest runner use "ios" as default OS (Plaform.OS) for react-native tests. How to do test in jest that have platform dependent code. An further more, how to mock static constant imported in a module.
Here is the code: utils.ts:
import { Platform } from "react-native";
export const isIOS = Platform.OS === "ios"; // note constant, not function
items.ts:
import { isIOS } from "@my/utils";
export const items = [{
id: 1,
name: isIOS ? "Apple" : "Android"
}]
test:
import { items } from "./items";
// not working because Platform.OS is used statically during import statement
it("should be android", () => {
Platform.OS = "android"; // too late...
expect(items[0].name).toBe("Android"); // fail: Apple
}
it("should be ios", () => {
Platform.OS = "ios";
expect(items[0].name).toBe("Apple"); // works due to default platform value in Jest
}
I saw some workaround using jest.resetModules()
& require
inside test/it block (and change Plaform.OS before require) but does exist a more simple way to achieve that ?
Upvotes: 1
Views: 3256
Reputation: 1276
In my code I have created a new constant called CustomPlatform
.
So in my code instead of Platform
from react-native
. I use CustomPlatform
from @/constants
import { Platform } from 'react-native'
const CustomPlatform = {
IS_IOS: Platform.OS === 'ios',
}
The code:
const permissionType = Platform.IS_IOS ? PERMISSIONS.IOS.CAMERA : PERMISSIONS.ANDROID.CAMERA
and then I can just use jest.replaceProperty(Platform, 'IS_IOS', false)
and with this approach I could also cover the android. But be aware in after this change you might want to revert this change at the end of the test otherwise it may affect other tests.
Upvotes: 0
Reputation: 1038
Simply replacing the iOS implementation with the Android implementation works. Use the other way around for Android.
jest.mock('react-native/Libraries/Utilities/Platform.ios.js', () => ({
...jest.requireActual(
'react-native/Libraries/Utilities/Platform.android.js',
),
}));
Upvotes: 0
Reputation: 214
In your test file
import { Platform } from 'react-native'
jest.doMock('react-native/Libraries/Utilities/Platform.android.js', () => ({
OS: 'android',
select: jest.fn(),
}))
jest.doMock('react-native/Libraries/Utilities/Platform.ios.js', () => ({
OS: 'android',
select: jest.fn(),
}))
describe('Platform', () => {
it('Should be android', () => {
expect(Platform.OS).toEqual('android')
})
it('Should be ios', () => {
Platform.OS = 'ios'
expect(Platform.OS).toEqual('ios')
})
it('Should be android', () => {
Platform.OS = 'android'
expect(Platform.OS).toEqual('android')
})
})
Upvotes: 3