title: How can I test functions that are provided by context using jest and react-testing-library?
body: <p>I have a <code>&lt;UserProvider /&gt;</code> component that provides context which has a <code>login</code> method in its value. In my test I want to check if that method has been called. How can I check to make sure this method is being called in my test if it comes from context? I've tried using the <a href="https://jestjs.io/docs/en/jest-object#jestspyonobject-methodname" rel="noreferrer">spyOn</a> and <a href="https://jestjs.io/docs/en/jest-object#jestspyonobject-methodname" rel="noreferrer">mock</a> methods but I can't get them to work.</p>
  
  <p>Here's my <code>UserProvider</code> component which provides the context.</p>
  
  <pre><code>import React, { useState, useContext, createContext } from 'react'
  
  const UserContext = createContext()
  
  function UserProvider({ children }) {
    const [user, setUser] = useState(null)
    const login = user =&gt; setUser(user)
  
    return &lt;UserContext.Provider value={{ user, login }}&gt;{children}&lt;/UserContext.Provider&gt;
  }
  
  const useUser = () =&gt; useContext(UserContext)
  
  export { UserProvider, useUser }
  </code></pre>
  
  <p>Here's my <code>Login</code> component using the context from <code>UserProvider</code> (via <code>useUser</code>)</p>
  
  <pre><code>import React from 'react'
  import { useUser } from './UserProvider'
  
  function Login() {
    const { login } = useUser()
  
    const handleSubmit = async e =&gt; {
      e.preventDefault()
  
      // I need to make sure this method is being called in my test.
      login({ name: 'John Doe' })
    }
  
    return (
      &lt;form onSubmit={handleSubmit}&gt;
        &lt;button&gt;Login&lt;/button&gt;
      &lt;/form&gt;
    )
  }
  
  export default Login
  </code></pre>
  
  <p>Here's my <code>Login</code> test</p>
  
  <pre><code>import React from 'react'
  import { render, fireEvent } from '@testing-library/react'
  import Login from './Login'
  import { UserProvider, useUser } from './UserProvider'
  
  // Is this correct?
  jest.mock('./UserProvider', () =&gt; ({
    useUser: jest.fn(() =&gt; ({
      login: jest.fn()
    }))
  }))
  
  it('should log a user in', () =&gt; {
    const { getByText } = render(
      &lt;UserProvider&gt;
        &lt;Login /&gt;
      &lt;/UserProvider&gt;
    )
  
    const submitButton = getByText(/login/i)
    fireEvent.click(submitButton)
  
    // How can I make this work?
    const { login } = useUser()
    expect(login).toHaveBeenCalledTimes(1)
  })
  </code></pre>
  
  <p>I have a <a href="https://codesandbox.io/s/great-pond-9xww9" rel="noreferrer">codesandbox</a> but it's erroring out about jest.mock not being a function so I don't know if it's very useful.</p>