📝
ReactNative(Expo)のアイコンをJestのSnapshotでテストする
概要
@expo/vector-icons
も、native-base
のIconでラッピングしても、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.ts
でsetupFilesAfterEnv
に指定してあるファイルにモックを書きました。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
native base 3.3.4
jest 26.6.3
Discussion