2017-04-01 76 views
6

一些我想測試代碼的檢測平臺,利用,如:懲戒開玩笑平臺檢測和應對本土

import { Platform } from 'react-native'; 
... 

if (Platform.OS === 'android') { 
    ... 
} else { 
    ... 
} 

有沒有用玩笑和/或別的東西來嘲笑這是一個明智的方式,所以我可以在一次測試中測試兩個分支?或者是將其解耦並將平臺放入例如上下文變量的智能方式?雖然它總是認爲重構代碼以使測試更容易,但這是一種騙局。

回答

2

這爲我工作(玩笑21.2.1,酶3.2.0)設置:

jest.mock('Platform',() => { 
    const Platform = require.requireActual('Platform'); 
    Platform.OS = 'android'; 
    return Platform; 
}); 

把它例如在測試的頂部,或者在a beforeAll

0

你可以嘲笑不管你從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 
    }); 
+0

這不是永久的嗎?即,這是不是意味着我需要在「afterEach」中「解鎖」?那可能嗎? –

+0

嗯,沒有這不起作用。 'jest.mock'被吊起來,所以它不在'beforeEach'之前,所以它在一切之前運行。一個可行的選擇似乎是在測試之前修補「RN.Platform.OS」對象。或者將平臺解耦到上下文中。 –

-1

你要嘲笑模塊,並將其導入到您的測試。然後你可以使用mockImplementation給它設置爲androidios

import reactNative from 'react-native'; 
jest.mock('react-native',() = > jest.fn(); 

it('is android',() => { 
    reactNative.mockImplementation(()=>({Platform:{OS: 'android'}})) 
    //test the android case 
}) 

it('is android',()=>{ 
    reactNative.mockImplementation(()=>({Platform: { OS: 'io' }})) 
    //test the ios case 
}) 
+1

我試過這個方法,但是我得到'_reactNative2.default.mockImplementation不是函數'。你有什麼主意嗎?謝謝。 – Dan

+0

這不會工作,因爲它被定義爲'ReactNative.Platform.OS',而不僅僅是'ReactNative.Platform' –

+0

你是對的我已經更新了答案 –

3

的方式,我取得了嘲諷設置平臺只是直接設置它在測試:

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,因爲理想的函數應該只有一個責任。但是,我確定您可以使用它來運行第一個測試,動態設置平臺並在一個函數中運行第二個測試。

-1

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() 
}) 
+0

Downvotes沒有任何解釋不會幫助任何人。請解釋 – acharlop

0

我使用的是從這個github上的問題https://github.com/facebook/jest/issues/1370#issuecomment-352597475

的解決方案,我感動的玩笑配置從package.json到單獨的文件。 到目前爲止,一切似乎都很好,包括: a)根據平臺導入正確的文件。例如,在ios:.ios.tsx上,然後是.native.tsx,然後輸入.tsx b)PLATFORM。IOS返回true運行測試IOS的時候,沒有必要嘲笑什麼

// 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" 
    ] 
    }, 
} 
1

由於其他的答案將無法正常工作,如果你想在一個試運行嘲笑在同一個測試套件和不同的操作系統,這是另一種方式。而不是直接在代碼中使用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'); 
    // ... 
} 

信用爲理念去this GitHub issue comment