jest+enzymeのテスト逆引き辞典(Typescript)

# ユーザーアクション
ユーザーアクションをきっかけにしたテストを実施する時のテストコード
## クリック
`simulate('click')`を使ってボタンをクリックさせる。
その後、propsが発火したことを確認する。

```typescript:テスト対象.tsx
type ButtonProps = {
  onClick: () => void
}


export const Button = (props: ButtonProps) => (
  <button className="Button" onClick={props.onClick}>
    ボタン
  </button>
)
```

```typescript:テストコード.tsx
it('click button', () => {
  const onClick = jest.fn()
  const wrapper = shallow(<Button onClick={onClick} />)
  wrapper.find('.Button').simulate('click')
  expect(onClick).toHaveBeenCalled()
})
```

## 文字入力
`simulate('change', { target: { value: inputValue }})`を使って`input`要素に値を入力させる。
その後、propsが発火したことを確認する。

```typescript:テスト対象.tsx
type InputProps = {
  value: string
  onChange: (value: string) => void
}

export const Input = (props: InputProps) => (
  <input className="Input" value={props.value} onChange={event => props.onChange(event.target.value)} />
)
```

```typescript:テストコード.tsx
it('input value', () => {
  const onChange = jest.fn()
  const wrapper = shallow(<Input value="" onChange={onChange} />)
  const inputValue = 'inputValue'
  wrapper.find('.Input').simulate('change', { target: { value: inputValue }})
  expect(onChange).toHaveBeenCalledWith(inputValue)
})
```



# props変化チェック
`setProps()`を利用してpropsを変化させる。

```typescript:テスト対象.tsx
type ButtonProps = {
  disabled: boolean
  onClick: () => void
}


export const Button = (props: ButtonProps) => (
  <button className="Button" onClick={props.onClick} disabled={props.disabled}>
    ボタン
  </button>
)
```

```typescript:テストコード.tsx
describe('check disabled', () => {
  let initDisabled: boolean
  let wrapper: ReturnType<typeof shallow>

  beforeEach(() => {
    initDisabled = false
    wrapper = shallow(<Button onClick={jest.fn()} disabled={initDisabled} />)
  })

  it('ready', () => {
    expect(wrapper.find('.Button').props().disabled).toBe(initDisabled)
  })

  it('change', () => {
    const changeDisabled = true
    wrapper.setProps({ disabled: changeDisabled })
    expect(wrapper.find('.Button').props().disabled).toBe(changeDisabled)
  })
})
```
<!-- # state変化チェック -->

# render内のチェック
render内にあるタグに対して何かアクションを起こしたり、タグがレンダリングされているかをチェックしたりする。
## renderされているコンポーネントのchildrenを確認する

```typescript:テスト対象.tsx
type ButtonProps = {
  onClick: () => void
}


export const Button = (props: ButtonProps) => (
  <button className="Button" onClick={props.onClick}>
    ボタン
  </button>
)
```

```typescript:テストコード.tsx
it('call onClick', () => {
  const wrapper = shallow(<Button onClick={jest.fn()} />)
  expect(wrapper.find('.Button').text()).toBe('ボタン')
})
```



## render内にあるタグのpropsを発火させてチェックする
shallowでテストしている場合、render内にあるタグのpropsを発火させてテストしたい場合がある。
例として、`TestComponent`コンポーネントの`onCallback`を発火させてみる。

```typescript:テスト対象.tsx
type ButtonProps = {
  onClick: () => void
}


export const Button = (props: ButtonProps) => (
  <TestComponent onCallBack={props.onClick} />
)

type TestComponentProps = {
  onCallBack: () => void
}

export const TestComponent = (props: TestComponentProps) => (
  <button onClick={props.onCallBack}>
    test
  </button>
)
```

```typescript:テストコード.tsx
it('call onClick', () => {
  const onClick = jest.fn()
  const wrapper = shallow(<Button onClick={onClick} />)
  wrapper.find(TestComponent).props().onCallBack()
  expect(onClick).toHaveBeenCalled()
})
```


ちなみに`shallow`ではなく`mount`でテストするなら、`.simulate('click')`でテスト可能である。

```typescript:テストコード.tsx
it('click button', () => {
  const onClick = jest.fn()
  const wrapper = mount(<Button onClick={onClick} />)
  wrapper.find(TestComponent).simulate('click')
  expect(onClick).toHaveBeenCalled()
})
```

## あるクラスがレンダリングされているかをチェックする
`find('.クラス名')`を使ってそのクラスを持っているタグを取得し、`length`を使ってレンダリングされていることをチェックする。

```typescript:テスト対象.tsx
export const TestComponent = () => (
  <div className="TestComponent">
    test
  </div>
)
```

```typescript:テストコード.tsx
it('check render TestComponent', () => {
  const wrapper = shallow(<TestComponent />)
  expect(wrapper.find('.TestComponent').length).toBe(1)
})
```

## ある要素がレンダリングされているかをチェックする
`find('タグ名')`を使ってそのクラスを持っている要素を取得し、`length`を使ってレンダリングされていることをチェックする。

```typescript:テスト対象.tsx
export const TestComponent = () => (
  <div className="TestComponent">
    test
  </div>
)
```

```typescript:テストコード.tsx
it('check render TestComponent', () => {
  const wrapper = shallow(<TestComponent />)
  expect(wrapper.find('div').length).toBe(1)
})
```

## Reactコンポーネントのあるpropsの値チェック
チェックしたいReactコンポーネントを`find()`で探して`props()`を使ってReactコンポーネントの属性値を取得します。

```typescript:テスト対象.tsx
type InputProps = {
  value: string
  onChange: (value: string) => void
}

export const Input = (props: InputProps) => (
  <input className="Input" value={props.value} onChange={event => props.onChange(event.target.value)} />
)
```

```typescript:テストコード.tsx
it('check set props in Input', () => {
  const value = 'value'
  const wrapper = shallow(<Input value={value} onChange={jest.fn()} />)
  expect(wrapper.find('.Input').props().value).toBe(value)
})
```

# Windowオブジェクト関係のテスト
## window.scrollTo()が発火したことを確認する
`jest.spyOn()`を利用して`window.scrollTo()`をモックして発火をテストする

```typescript:テスト対象.tsx
export const Button = () => (
  <button className="Button" onClick={() => window.scrollTo(0, 0)}>
    トップへ
  </button>
)
```

```typescript:テストコード.tsx
it('call windowScrollTo', () => {
  const scrollTo = jest.fn()
  const mockWindowScrollTo = jest.spyOn(window, 'scrollTo').mockImplementation(scrollTo)
  const wrapper = shallow(<Button/>)
  wrapper.find('.Button').simulate('click')
  expect(scrollTo).toHaveBeenCalled()
})

```

<!-- # アロー関数のチェック -->
<!-- # fetch系 -->