我试图测试的一些代码检测平台,例如使用:
import { Platform } from 'react-native';
...
if (Platform.OS === 'android') {
...
} else {
...
}
是否有一种明智的方法可以用Jest和/或其他东西来模拟这个,所以我可以在一次测试中测试两个分支?
或者是将它解耦并将平台放入例如上下文变量的智能方法?虽然总是感觉重组代码使其更容易测试是一种欺骗。
我试图测试的一些代码检测平台,例如使用:
import { Platform } from 'react-native';
...
if (Platform.OS === 'android') {
...
} else {
...
}
是否有一种明智的方法可以用Jest和/或其他东西来模拟这个,所以我可以在一次测试中测试两个分支?
或者是将它解耦并将平台放入例如上下文变量的智能方法?虽然总是感觉重组代码使其更容易测试是一种欺骗。
这对我有用 (Jest 21.2.1,Enzyme 3.2.0):
jest.mock('Platform', () => {
const Platform = require.requireActual('Platform');
Platform.OS = 'android';
return Platform;
});
把它放在测试的顶部,或者放在 一个 beforeAll
例如。
这对我有用 (Jest 21.2.1,Enzyme 3.2.0):
jest.mock('Platform', () => {
const Platform = require.requireActual('Platform');
Platform.OS = 'android';
return Platform;
});
把它放在测试的顶部,或者放在 一个 beforeAll
例如。
我实现模拟设置平台的方式只是直接在测试中设置:
it('should only run for Android', () => {
Platform.OS = 'android'; // or 'ios'
// For my use case this module was failing on iOS
NativeModules.MyAndroidOnlyModule = {
fetch: jest.fn(
(url, event) => Promise.resolve(JSON.stringify(event.body))
),
};
return myParentFunction().then(() => {
expect(NativeModules.MyAndroidOnlyModule.fetch.mock.calls.length).toBe(1);
expect(fetch.mock.calls.length).toBe(0);
});
});
这将设置平台仅在测试期间在Android上运行,以确保我的功能仅调用特定功能。我在平台相关编译中包含的函数如下所示:
export default function myParentFunction() {
if (Platform.OS === 'ios') {
return fetch();
}
return NativeModules.MyAndroidOnlyModule.fetch();
}
我建议只创建两个不同的测试,一个平台设置为iOS,另一个设置为Android,因为理想情况下,一个功能应该只有一个责任。但是,我确信您可以使用它来运行第一个测试,动态设置平台并在一个函数中运行第二个测试。
如果您想要模拟不同的操作系统,其他答案将无效 在同一个测试套件中 和 在一次试运行中,这是另一种方式。而不是使用 Platform.OS
直接在你的代码中,在某处定义一个辅助函数并使用它:
export function getOS() {
return Platform.OS;
}
这个功能 能够 然后在你的测试中嘲笑它,例如
it('does something on Android', () => {
helpers.getOS = jest.fn().mockImplementationOnce(() => 'android');
// ...
}
it('does something else on iOS', () => {
helpers.getOS = jest.fn().mockImplementationOnce(() => 'ios');
// ...
}
这个想法值得信赖 这个GitHub问题评论。
也许是“导入”方法中的问题,请检查:
const isAndroid = require('app/helpers/is_android');
//import isAndroid from 'app/helpers/is_android'
使用“导入”这将无法正常工作,需要使用“require”。
beforeEach(() => {
jest.resetModules();
});
it("should be true when Android", () => {
jest.mock('Platform', () => {
return { OS: 'android' };
});
expect(isAndroid).toBe(true);
});
使用 jest.doMock 和 jest.resetModules
jest.resetModules()
jest.doMock('react-native', () => ({ Platform: { OS: 'android' }}))
你可以模仿你想要的任何东西 React-Native
喜欢这个:
describe('notifications actions tests', () => {
let Platform;
beforeEach(() => {
jest.mock('react-native', () => ({
Platform: {
...
}));
Platform = require('react-native').Platform; // incase u would like to refer to Platform in your tests
});
我正在使用这个github问题的解决方案 https://github.com/facebook/jest/issues/1370#issuecomment-352597475
我从中移动了jest配置 package.json
分开文件。
到目前为止,一切似乎都很好,包括:
a)根据平台导入正确的文件。例如,在ios:.ios.tsx上,然后是.native.tsx,然后是.tsx
b)PLATFORM.IOS在运行test-ios时返回true,不需要模拟任何东西
// package.json
"scripts": {
"test": "cross-env NODE_ENV=test jest --config config/jest.desktop.json",
"test-ios": "cross-env NODE_ENV=test jest --config config/jest.ios.json",
"test-android": "cross-env NODE_ENV=test jest --config config/jest.android.json"
}
// config/jest.web.json
{
...
}
// config/jest.ios.json
{
...
"preset": "react-native",
"haste": {
"defaultPlatform": "ios",
"platforms": [
"android",
"ios",
"native"
],
"providesModuleNodeModules": [
"react-native"
]
},
}
// config/jest.android.json
{
...
"preset": "react-native",
"haste": {
"defaultPlatform": "android",
"platforms": [
"android",
"ios",
"native"
],
"providesModuleNodeModules": [
"react-native"
]
},
}
import React from "react";
import renderer from "react-test-renderer";
import SmartText from "../SmartText";
describe("markdown smart text component", () => {
beforeEach(() => {
jest.resetModules();
});
it("renders with props on ios", () => {
jest.mock("Platform", () => {
return { OS: "ios" };
});
expect(
renderer.create(<SmartText title="code ios" code />).toJSON()
).toMatchSnapshot();
});
it("renders with props on android", () => {
jest.mock("Platform", () => {
return { OS: "android" };
});
expect(
renderer.create(<SmartText title="code android" code />).toJSON()
).toMatchSnapshot();
});
});
可以为每个测试直接设置OS
test('android', () => {
Platform.OS = 'android'
const component = renderer.create(<Component />).toJSON()
expect(component).toMatchSnapshot()
})
test('ios', () => {
Platform.OS = 'ios'
const component = renderer.create(<Component />).toJSON()
expect(component).toMatchSnapshot()
})