質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • React Native

    256questions

    React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

ReactNative:snapshotのテストにおけるMockの方法が分かりません

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 614

mariek

score 2

前提・実現したいこと

現在、ReactNativeで、iPad、Windows Tabletをターゲットとしたタブレットアプリを開発しています。
APIから取得したプロジェクト一覧を表示するような画面を実装して、
jestのsnapshotを使って画面のテストを実装してみたのですが、
APIの呼び出し部分のMockの方法が分からず困っています。

ご回答よろしくお願いいたします。

該当のソースコード

Home.js

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  FlatList,
  View,
  TouchableHighlight,
} from 'react-native';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as actions from '../Actions';
import 'fetch-everywhere';

class Home extends Component {
  constructor(props) {
    super(props);
    this.state = {
      projects: [],
    };
  }

  componentWillMount = (props) => {
    const { dispatch } = this.props;
    // ここでプロジェクト一覧のデータを取得するAPIの呼び出し
    this.props.actions.getAllProjects();
  }

  render() {
    const props = this.props;
    const { navigate } = this.props.navigation;

    return (
      <View>
        <FlatList style={styles.list}
          // APIから取得したデータを取り出す(※ここをMockしたい※)
          // 今の状態でテストするとdataの中身が空になります
          data={props.projects.getAllProjects.projects}
          renderItem={({item}) => 
            <TouchableHighlight onPress={() => navigate('Project', { project: item })} underlayColor='paleturquoise'>
              <View style={styles.project}>
                <Text style={styles.projectName}>{item.title}</Text>
              </View>
            </TouchableHighlight>
          }
        />
      </View>
    );
  }
};

const styles = StyleSheet.create({
  project: {
    margin: 10,
  },
  list: {
    marginTop: 20,
  },
  projectName: {
    fontSize: 20,
    textAlign: 'left',
    flex: 1,
  },
});

const mapStateToProps = (state) => {
  return {
    projects: state,
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    actions: bindActionCreators(actions, dispatch)
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Home)

index.ios.js(テストコード)

import 'react-native';
import React from 'react';
import Index from '../index.ios.js';

// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer';

it('renders correctly', () => {
  const tree = renderer.create(
    <Index />
  ).toJSON();
  expect(tree).toMatchSnapshot();
});


index.ios.js.snap(自動生成されたスナップショット)

// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renders correctly 1`] = `
<View
  style={
    Object {
      "alignItems": "center",
      "backgroundColor": "#F5FCFF",
      "flex": 1,
      "justifyContent": "center",
    }
  }
>
  <View>
    <Text
      accessible={true}
      allowFontScaling={true}
      disabled={false}
      ellipsizeMode="tail"
      style={
        Object {
          "fontSize": 30,
          "fontWeight": "bold",
          "marginTop": 20,
          "textAlign": "center",
        }
      }
    >
      プロジェクト一覧
    </Text>
    <RCTScrollView
      ListHeaderComponent={undefined}
      // 今の状態だとdataの中身が空
      data={Array []}
      disableVirtualization={false}
      getItem={[Function]}
      getItemCount={[Function]}
      horizontal={false}
      initialNumToRender={10}
      keyExtractor={[Function]}
      maxToRenderPerBatch={10}
      numColumns={1}
      onContentSizeChange={[Function]}
      onEndReachedThreshold={2}
      onLayout={[Function]}
      onMomentumScrollEnd={[Function]}
      onScroll={[Function]}
      onScrollBeginDrag={[Function]}
      onScrollEndDrag={[Function]}
      onViewableItemsChanged={undefined}
      renderItem={[Function]}
      renderScrollComponent={[Function]}
      scrollEventThrottle={50}
      stickyHeaderIndices={Array []}
      style={
        Object {
          "marginTop": 20,
        }
      }
      updateCellsBatchingPeriod={50}
      windowSize={21}
    >
      <View />
    </RCTScrollView>
  </View>
</View>
`;
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

React の思想や Jest のスナップショットテスティングのやりかたとして次があります

  • テスト対象: あるコンポーネントに対して
  • 入力: 特定の props を与えたときに
  • 出力: 想定した仮想 DOM ツリーになる

ですので、コンポーネントとしてテスト可能にするために data を props として与えてやる設計として、 data prop のパターンをいくつか作ってテストしてやる、というのが妥当かなと思います

API のテストは別で async/await を使ったテストケースを作ってやればよいでしょう

答えになっていますでしょうか ?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/08/03 15:35

    ご回答ありがとうございます!
    > コンポーネントとしてテスト可能にするために `data` を props として与えてやる設計として、 `data` prop のパターンをいくつか作ってテストしてやる、
    設計を変更するかどうかは改めて検討したいと思います。

    現在の設計を変更せずに、テストコードを工夫してMockする方法はないということでしょうか・・?

    キャンセル

  • 2017/08/03 16:41

    `projects.getAllProjects.projects` にダミーデータを入れて `Home` コンポーネントに props として `projects` を渡すことでいけそうですが

    キャンセル

  • 2017/08/04 10:53

    ご回答ありがとうございます。
    教えていただいた情報でちょっと試してみたいと思います。
    試した結果、またご報告させていただきます!

    キャンセル

同じタグがついた質問を見る

  • React Native

    256questions

    React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。