blitz-js / legacy-framework

MIT License
2 stars 2 forks source link

Unable to mock query/mutation resolver #165

Closed dhythm closed 2 years ago

dhythm commented 2 years ago

What is the problem?

As I create a discussion https://github.com/blitz-js/blitz/discussions/3112#discussioncomment-1924103, the mock for query/mutation resolver does not work at blitz 0.44.4. (it works well at older blitz version.) It might be a regression. So I create an issue 🙏

Paste all your error logs here:

image

Paste all relevant code snippets here:

https://github.com/dhythm/blitz-sample

jest app/pages/index.test.tsx

What are detailed steps to reproduce this?

  1. blitz new myApp (install blitz @0.44.4)
  2. replace test.skip with test for index.test.tsx
  3. mock getCurrentUser instead of useCurrentUser
  4. run jest

Run blitz -v and paste the output here:

Loaded env from /Users/y-okada/local/blitz-sample/.env.local
Loaded env from /Users/y-okada/local/blitz-sample/.env
macOS Catalina | darwin-x64 | Node: v14.15.4

blitz: 0.44.4 (local)

  Package manager: npm 
  System:
    OS: macOS 10.15.7
    CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 897.34 MB / 16.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 14.15.4 - ~/.anyenv/envs/nodenv/versions/14.15.4/bin/node
    Yarn: 1.22.11 - ~/.anyenv/envs/nodenv/versions/14.15.4/bin/yarn
    npm: 6.14.10 - ~/.anyenv/envs/nodenv/versions/14.15.4/bin/npm
    Watchman: 2021.06.07.00 - /usr/local/bin/watchman
  npmPackages:
    @prisma/client: 3.7.0 => 3.7.0 
    blitz: 0.44.4 => 0.44.4 
    prisma: 3.7.0 => 3.7.0 
    react: 18.0.0-beta-149b420f6-20211119 => 18.0.0-beta-149b420f6-20211119 
    react-dom: 18.0.0-alpha-5ca4b0433-20211020 => 18.0.0-alpha-5ca4b0433-20211020 
    typescript: ~4.5 => 4.5.4 

Please include below any other applicable logs and screenshots that show your problem:

No response

beerose commented 2 years ago

Hey @dhythm. I finally had some time to take a look. I managed to get it working with the following changes:

import getCurrentUser from "app/users/queries/getCurrentUser"
import { screen } from "test/utils"

jest.mock("app/users/queries/getCurrentUser")
const mockUseGetUser = getCurrentUser as jest.MockedFunction<typeof getCurrentUser>

test("renders blitz documentation link", async () => {

  mockUseGetUser.mockResolvedValue({
    id: 1,
    name: "User",
    email: "user@email.com",
    role: "user",
  })

  const logoutButton = await screen.findByRole("button", { name: "Logout" })
  expect(logoutButton).toBeInTheDocument()
})
  1. I changed mockRehectedValue to mockResolvedValue.
  2. Used await to wait for the button with Logout.

Let me know if that helps.

dhythm commented 2 years ago

Hi @beerose. Thanks for having time about this issue. Sorry, using mockRejectedValue is my failure 🙇‍♂️

I tried the test again with the following code. However, it was failed yet.

import getCurrentUser from "app/users/queries/getCurrentUser"
import { render, screen } from "test/utils"
import Home from "."

jest.mock("app/users/queries/getCurrentUser")
const mockGetCurrentUser = getCurrentUser as jest.MockedFunction<typeof getCurrentUser>

test("renders blitz documentation link", async () => {
  // This is an example of how to ensure a specific item is in the document
  // But it's disabled by default (by test.skip) so the test doesn't fail
  // when you remove the the default content from the page
  render(<Home />)

  // This is an example on how to mock api hooks when testing
  mockGetCurrentUser.mockResolvedValue({
    id: 1,
    name: "User",
    email: "user@email.com",
    role: "user",
  })

  const logoutButton = await screen.findByRole("button", { name: "Logout" })
  expect(logoutButton).toBeInTheDocument()
})

At blitz v0.44.4 image

And also tried at blitz v0.45.2 (created by blitz new again) image

dhythm commented 2 years ago

It looks not to mock getCurrentUser 🤦‍♂️

beerose commented 2 years ago

Hi @dhythm, I created a PR to your repo with all my code changes: https://github.com/dhythm/blitz-sample/pull/1. You'd need to run blitz codegen (to generate routes and fix the error on your last screenshot) before running the test

dhythm commented 2 years ago

Hi @beerose, I've confirmed your PR and the test worked well!! I guess blitz codegen seems important for this case. So, I'll try to mock RPC resolver for other repo (much more complicated one).

Thanks for your help!!

beerose commented 2 years ago

No problem!

dhythm commented 2 years ago

@beerose and folks! I just found another issue 🤦‍♂️ , so re-open this issue.

When UserInfo has two useQuerys like

  const currentUser = useCurrentUser()
  const users = useUsers()

and index.test.tsx mocks them as

jest.mock("app/users/queries/getCurrentUser")
const mockGetCurrentUser = getCurrentUser as jest.MockedFunction<typeof getCurrentUser>

jest.mock("app/users/queries/getUsers")
const mockGetUsers = getUsers as jest.MockedFunction<typeof getUsers>

...

  mockGetCurrentUser.mockResolvedValue({
    id: 1,
    name: "User",
    email: "user@email.com",
    role: "user",
  })
  mockGetUsers.mockResolvedValue([
    {
      id: 1,
      name: "User",
      email: "user@email.com",
      role: "user",
    },
    {
      id: 2,
      name: "User2",
      email: "user2@email.com",
      role: "user2",
    },
  ])

Run the test and watch console.log, then the log returns

      {
        currentUser: { id: 1, name: 'User', email: 'user@email.com', role: 'user' },
        users: { id: 1, name: 'User', email: 'user@email.com', role: 'user' }
      }

Looks like useQuery always returns the first mock 👀 I meet this issue in another repo. (It would happen not only this repo but also other repos.)

If I mock useCurrentUser hook instead of getCurrentUser, then getUser is correctly mocked.

The latest code is here: https://github.com/dhythm/blitz-sample/blob/master/app/pages/index.test.tsx

dhythm commented 2 years ago

If it is good to raise a new issue, I'll be happy to do 👍

dhythm commented 2 years ago

open a new issue blitz-js/blitz#3148, so close this issue