React-Native Use Jest测试AppState

时间:2020-01-02 09:09:56

标签: react-native event-listener

如何触发AppState侦听器以检查其是否正常运行?

<FlatList
                style={UI.styles.screen}
                data={this.state.data}
                keyExtractor={(item) => String(item.id)}
                renderItem={this._renderSection.bind(this)}


            />

Jest中是否有一种方法可以触发此侦听器?

2 个答案:

答案 0 :(得分:3)

是的,如果知道本地模块的位置,则可以模拟它们。下面是一个示例,其中我测试了当应用程序状态更改时,应用程序状态服务是否调度了给定操作:

  it('if a store is set dispatches an APP_STATE_CHANGE action with the new state on change', () => {

    let capturedChangeCallback = null

    const mockAddListener = jest.fn((event, callback) => {
      if (event === 'change') {
        capturedChangeCallback = callback
      }
    })

    jest.resetModules()
    jest.doMock('react-native/Libraries/AppState/AppState', () => ({
      addEventListener: mockAddListener,
    }))
    const mockStore = { dispatch: jest.fn() }

    const svc = require('@services/appState').default
    svc.setStore(mockStore)

    // change called
    capturedChangeCallback('active')

    expect(mockStore.dispatch).toHaveBeenCalledTimes(1)
    expect(mockStore.dispatch).toHaveBeenCalledWith({
      type: 'APP_STATE_CHANGE',
      payload: 'active',
    })
  })

这里的关键是jest.doMock调用传递完整的AppState模块位置,并调用resetModules以确保隔离测试用例。

答案 1 :(得分:0)

您可以在组件中通过AppState作为默认属性,并且在测试时可以提供所需的任何值。例如,如果您有一个组件AppApp.js/App.tsx看起来像这样,

import { AppState as AppStateProp,View} from "react-native";
import React, { useEffect } from "react";

function App({AppState=AppStateProp}){

 const appState = useRef(AppState.currentState);

 const onAppStateChange = (nextState)=>{
     console.log(`Next state ${nextState}`);
     appState.current = nextAppState;
 }

  useEffect(()=>{
     AppState.addEventListener('change', onAppStateChange);
     return ()=> AppState.removeListener('change',onAppStateChange)
  },[])
  
  return (

      <View>
       // your ui here
      </View>
  )


}

您可以创建如下的单元测试

test("It should console log", () => {

let map = {}
    const AppState = {
     currentState: "background",
     addEventListener: jest.fn((event, callback) => {
         map[event] = callback;
     }),
     removeEventListener: jest.fn((event, callback) => {}),
    };
    const AppScreen = <App AppState={AppState} />;
    const { getByTestId } = render(
           AppScreen
        );
    map.change('active') // here active is next App state
}

尽管这不是有效的测试用例,但您可以触发任何状态更改并在此处进行验证