2

I am pretty new to testing and attempting to write what should be a simple test for our project...

test('Attempt Login', async () => {
   const submitHandler = jest.fn( ()=> console.log('hello'))

  const { debug, getByText, getByTestId, getByPlaceholderText } = render
    (
    <Router>
        <LoginPage submitHandler={submitHandler} />
    </Router> 
    )

    fireEvent.change(getByPlaceholderText("Enter Username"), {
      target: { value: "admin" }
    });

    fireEvent.change(getByPlaceholderText("Enter Password"), {
      target: { value: "Password" }
    });


    fireEvent.click(getByTestId("login-btn"));

    expect(submitHandler).toHaveBeenCalled()
})

My button inside of login

   <Button data-testid="login-btn" type="submit" variant="contained" color="primary"
   onClick={(event)=>submitHandler(event)}>

the testing error

expect(jest.fn()).toHaveBeenCalled()

    Expected number of calls: >= 1
    Received number of calls:    0

      45 |     fireEvent.click(getByTestId("login-btn"));
      46 |   
    > 47 |     expect(submitHandler).toHaveBeenCalled()
         |                           ^
      48 | })
      49 | 
      50 | 

Thanks in advance for any help. I spent way too long on this already -_-

EDIT: attempting to test for the results of clicking the login button

Heres what I'm going trying:

mock an Axios call to the login route
await waitForElement getByText('home')
expect getbytext('home')

Am I on the right track?

Do I need to import the redirect page component and place it inside the router? for example the component for it to redirect to it?

6
  • 1
    I tried recreating the minimal example here: codesandbox.io/s/withered-pine-5185k and it worked (see Tests tab on the right). It might be a problem with a Button component that you use (could you tell where it is coming from) or with something in the other part of your LoginPage - hard to tell without the rest of the code. Commented May 1, 2020 at 0:50
  • I tried to re-create a version of my code. codesandbox.io/s/practical-morning-bldhe?file=/src/App.test.js I have another problem though, the aftereach(cleanup) doesn't seem to be working and it keeps re-rendering ? Commented May 1, 2020 at 3:25
  • So I finally figured out what was wrong. The example i was following was passing in the function submitHandler as a prop into login. my login button has onClick={submitHandler} if i change it to onClick={props.submitHandler} the test will pass. the question is now im trying to call a function in login that is not passed in as a prop. How do i Mock that function in testing..? Commented May 1, 2020 at 18:27
  • 1
    There is no way to mock this function in a form that I can see in your codesandbox. The one way is to move this function out of the component, into different file and then mock it in test, something like described here: jestjs.io/docs/en/manual-mocks#mocking-user-modules. However, I would strongly advise against doing it, as you would be mocking really low level code. Instead, why not, instead of verifying a function was called, just check the expected result. Not sure what would be in your case, but I see that you are redirecting to some page. Maybe this or something close? Commented May 1, 2020 at 23:08
  • I'm pretty new to testing, and I wanted to take it incrementally. I was planning to test for the result once I figured out how to get this working properly. you are correct it should redirect to a new page, but its not actully doing it. Commented May 2, 2020 at 4:08

2 Answers 2

3

You should use waitFor in this case:

...
await waitFor(() => expect(submitHandler).toHaveBeenCalled())
...

More info HERE

Sign up to request clarification or add additional context in comments.

1 Comment

Been struggling with this for a few hours. Other tests in the same codebase did not have to use waitFor however this was the fix that helped these tests pass.
0

As you already figured out, the problem is you are passing the submitHandler mock into LoginPage but you are not using that prop.

To answer your second question

How do I mock a function not passed in as a prop?

Here is how you can mock functions imported from different files with Jest:

import { submitForm } from './ajax.js'; // the function to mock
jest.mock('./ajax.js'); // jest mocks everything in that file

it('should call submitForm correctly', async () => {
  submitForm.mockResolvedValue({ loggedIn: true });
  render(<LoginPage />);
  
  userEvent.click(screen.getByRole('button', { name: 'Login' }));

  expect(submitForm).toHaveBeenCalledTimes(1);
  expect(await screen.findByText('You have logged in successfully')).toBeInTheDocument();
});

Useful links

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.