📝

ReactNative(Expo)のアイコンをJestのSnapshotでテストする

2022/01/29に公開

概要

@expo/vector-iconsも、native-baseIconでラッピングしても、Jestのスナップショットは<Text />になってしまいます。

import * as React from 'react';
import { View } from 'react-native';
import { Icon } from 'native-base';
import { FontAwesome5 } from '@expo/vector-icons';

function App() {
  return(
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Icon as={FontAwesome5} name="user" size={30} />
      <FontAwesome5 name="ban" size={30} color="white" />
    </View>
  )
}

これをスナップショットとると

<View
  style={
    Object {
      "alignItems": "center",
      "flex": 1,
      "justifyContent": "center",
    }
  }
>
  <Text />
  <Text />
</View>

こんな感じになります。動的にアイコンを切り替える場合などはスナップショットに反映された方いいのでモックを使ってそれっぽくスナップショットが取れるようにしてみました。

モック

test/config/setup.ts

jest.config.tssetupFilesAfterEnvに指定してあるファイルにモックを書きました。native-base@expo/vector-icons共にモックを作成します。

jest.mock('native-base', () => {
  const Original: {[key: string]: any} = jest.requireActual('native-base')

  const Mock: {[key: string]: any} = {...Original}
  Mock.Icon = 'Icon'

  return Mock
});
jest.mock('@expo/vector-icons', () => {
  const Original: {[key: string]: any} = jest.requireActual('@expo/vector-icons')

  const Mock: {[key: string]: any} = {...Original};
  const libraries: Array<string> = [
    'AntDesign',
    'Entypo',
    'EvilIcons',
    'Feather',
    'Fontisto',
    'FontAwesome',
    'FontAwesome5',
    'Foundation',
    'Ionicons',
    'MaterialCommunityIcons',
    'MaterialIcons',
    'Octicons',
    'SimpleLineIcons',
    'Zocial'
  ];

  libraries.forEach(key => Mock[key] = key);

  return Mock;
});

結果

スナップショットは下記のように変わります。

<View
  style={
    Object {
      "alignItems": "center",
      "flex": 1,
      "justifyContent": "center",
    }
  }
>
  <Icon
    as="FontAwesome5"
    name="user"
    size={30}
  />
  <FontAwesome5
    color="white"
    name="ban"
    size={30}
  />
</View>

面白いのは、Mock.Icon = 'Icon'とテキストにすり替えただけでprops付きでそれっぽく出力されるんですね。

まだ、expoのJestも慣れてないので丸っとテキストにすり替えちゃっていいのか、requireしたライブラリをobjectに変換していいのか自信ないですけど、一応native-baseの他のコンポーネントも動いてるし、アイコンライブラリ自体のテストを自分で書くことはないので多分大丈夫かなと・・・(できるかわからんけど)スナップショットの時だけすり替えた方がいいですかね?

何か突っ込みあったらコメントいただけると嬉しいです。

使ってるバージョン

expo SDK44
https://expo.dev/

native base 3.3.4
https://nativebase.io/

jest 26.6.3
https://jestjs.io/docs/26.x/getting-started

Discussion