vendredi 20 avril 2018

Async integration test issues w/Jest & react-testing-library

This test is working (most of the time), but only when using setTimeout. I can't figure out why wait from react-testing-library doesn't work (commented out), although I'm guessing it's because I'm ignorant about something. I am intentionally NOT mocking axios with this test (and related tests), as that would destroy most confidence in the integration test.

The problem is that occasionally the test would fail because it takes longer than 500ms to get a response back from the server when registering a new user. Also, it forces each test that uses this method to take at a minimum that 500ms, thus making it take potentially much longer than it needs to run all the tests.

Any suggestions would be greatly appreciated.

Test

it('Registers a user when email and password are provided', async (done) => {
      expect.assertions(2)

      const wrapper = renderSetupWithRedux()
      const { registerUserForm, getByTestId, store } = wrapper
      const passwordInput = getByTestId('register-user-form-password')
      const emailInput = getByTestId('register-user-form-email')

      emailInput.value = userCreds.email 
      fireEvent(emailInput, new Event('change', {
        bubbles: true,
        cancelable: true,
      }))

      passwordInput.value = userCreds.password 
      fireEvent(passwordInput, new Event('change', {
        bubbles: true,
        cancelable: true,
      }))

      fireEvent(registerUserForm, new Event('submit', {
        bubbles: true,
        cancelable: true,
      }))

      // let stateAfterSubmit
      // await wait(() => stateAfterSubmit = store.getState())

      // need to wait for the response from the auth server (not able to get this to work with "wait" right now)
      setTimeout(() => {
        done()
        const stateAfterSubmit = store.getState()
        expect(stateAfterSubmit.auth.user.email).toBe(userCreds.email)
        expect(stateAfterSubmit.auth.authed).toBe(true)

        integrationStore = store // preserve store for next tests
      }, 500)
    })

renderSetupWithRedux

function renderSetupWithRedux(store = integrationStore, overrides) {
  const wrapper = renderWithRedux(
    <div>
      <RegisterUserForm />
      <LogoutForm />
      <LoginForm />
    </div>,
    { store },
  )
  const loginForm = wrapper.getByTestId('login-form')
  const logoutFormButton = wrapper.getByTestId('logout-form-button')
  const registerUserForm = wrapper.getByTestId('register-user-form')
  const initialState = wrapper.store.getState()

  return {
    ...wrapper,
    initialState,
    loginForm,
    logoutFormButton,
    registerUserForm,
    ...overrides,
  }
}

renderWithRedux

export function renderWithRedux(
  ui,
  { initialState, store = createStore(reducer, initialState) } = {},
) {
  return {
    ...renderIntoDocument(<Provider store={store}>{ui}</Provider>),
    store,
  }
}

Aucun commentaire:

Enregistrer un commentaire