お知らせ

現在サイトのリニューアル作業中のため、全体的にページの表示が乱れています。
投稿日:
言語::TypeScript開発::テストNode.js::Jest

単体テストの観点でいうとprocess.argvそのものはモックしないほうが良いと思っているので、本記事ではprocess.argv自体をモックする方法と、それを回避する方法を紹介する

サンプルコード

正攻法

describe('example', () => {
  afterEach(() => {
    // 元に戻しておく
    process.argv.length = 2;
  });
  it('got first param', () => {
    process.argv.push('param1');
    expect(process.argv.length).toBe(3);
    expect(process.argv[2]).toBe('param1');
  });
});

そもそもモックせずに済むように設計する

process.argvを利用している関数でprocess.argvを引数に取ればモック不要となる

const getArgv = (argv: string[]) => {
    // some procedure
}

describe('getArgv', () => {
  it('got first param', () => {
    const argv = [,, 'param1'];
    expect(argv.length).toBe(3);
    expect(argv[2]).toBe('param1');
  });
});

フックを単体でテストするケースを想定。

このパターンはコンポーネントからフックを切り離しているケースで有用。手法としては@testing-library/react-hooksrenderHook()を使う。

カスタムフック

export const useUserForm = () => {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');

  const onChangeUserName = (ev: string) => {
    setUsername(ev);
  };
  const onChangePassword = (ev: string) => {
    setPassword(ev);
  };

  return {
    username,
    password,
    onChangeUserName,
    onChangePassword,
  };
};

テストコード

it('onChangeUserName で username が設定されること', () => {
  // `renderHook` で Hook をレンダリング
  const { result } = renderHook(() => useUserForm());
  // `act()` で Hook のイベントを叩く
  act(() => result.current.onChangeUserName('foo'));
  // 結果を見る
  expect(result.current.username).toBe('foo');
});