Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hooks Testing 🎣 #274

Merged
merged 12 commits into from
Feb 5, 2019
Merged

Conversation

donavon
Copy link
Contributor

@donavon donavon commented Jan 22, 2019

What:

Add a testHook utility

Why:

You can't call a Hook directly as it must run in context of a React component.

How:

testHook creates a component under-the-hood that calls back to the test where you can safely call the Hook. This so that the Hook can run within the context of a component, but set local deconstructed variables.

Here is an example of how to test a counter component.

test('useCounter', () => {
  let count, increment
  testHook(() => ({count, increment} = useCounter({ initialCount: 2 })))

  expect(count).toBe(2)
  increment()
  expect(count).toBe(3)
})

(see above test running live in CodeSandbox)

Any type of return types are supported in hookTester: objects, arrays, string, etc.

See discussion on #261 for more details.

Checklist:

  • Documentation - under a separate PR into docs repo
  • Tests
  • Ready to be merged (HOLD until Hooks is released into prod with React 16.8)
  • Added myself to contributors table

@gnapse
Copy link
Member

gnapse commented Jan 22, 2019

Nice!

Some things off the top of my head that would be nice to add:

  • More info about testHook in the README (I assume you knew this one and this is WIP)
  • Type definitions for testHook in typings/index.d.ts
  • Examples of tests using testHook under examples/
  • Ideally some examples of using it would use something more than custom hooks based on just useState or useReducer. I'd love to see examples that showcase that testing a custom hook's side effects is also possible.

@alexkrolick
Copy link
Collaborator

Implementation looks good.

  • For the Readme, just adding a link to a new react-hooks example should be sufficient
  • Same example should go in the docs PR
  • Once merged, @kentcdodds can add the example to the Codesandbox
  • Also OK with iterating on the examples if we have at least one to start, even if it wraps a built-in hook. This can happen in the docs or Codesandbox.

This will need to be bumped to the non-alpha in a few weeks when Hooks lands in 16.8.0
@donavon
Copy link
Contributor Author

donavon commented Jan 22, 2019

I've added examples/use-counter.js but in order to test it, it requires a build of React that supports Hooks. Thus... I had to change the devDependencies for rest and react-dom to 16.8.0-alpha.1.

This will need to be bumped to the non-alpha in a few weeks when Hooks lands in 16.8.0.

So... this PR should be held and not merged until Hooks lands in production.

@donavon
Copy link
Contributor Author

donavon commented Jan 22, 2019

README updated with link to use-counter example.

package.json Outdated
"react": "^16.5.2",
"react-dom": "^16.5.2",
"react": "16.8.0-alpha.1",
"react-dom": "16.8.0-alpha.1",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if we put ^16.5.2 || 16.8.0-alpha.1 here?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like it resolves 16.7.0 (no pre-release) https://semver.npmjs.com/

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The version here will have to be something that gets us hooks otherwise our tests will fail. Our peerDependencies thing is what matters most anyway.

@alexkrolick
Copy link
Collaborator

alexkrolick commented Jan 23, 2019

@kentcdodds @donavon what do you think of removing the examples folder in favor of the pages in the docs with the same code, and the Codesandbox? Then we don't have to worry about the package version or dependencies for the examples.

Another idea is to make a package.json for the examples folder.

Copy link
Member

@kentcdodds kentcdodds left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like hooks are getting released soon so I'm fine waiting to merge this until hooks are stable (then we can update the devDependency to reference a stable react version).

package.json Outdated
"react": "^16.5.2",
"react-dom": "^16.5.2",
"react": "16.8.0-alpha.1",
"react-dom": "16.8.0-alpha.1",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The version here will have to be something that gets us hooks otherwise our tests will fail. Our peerDependencies thing is what matters most anyway.

examples/react-hooks.js Show resolved Hide resolved
/**
* Renders a test component that calls back to the test.
*/
export function testHook(callback: () => void): void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to do anything special to indicate that the callback will be called with the result of the custom hook (so you can get type safety there) or is TypeScript's inference good enough to know?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the callback isn't called with anything and isn't required to return anything. i'm not a TS expert, so I'll defer, but this should work.

src/index.js Outdated Show resolved Hide resolved
@kentcdodds
Copy link
Member

Oh, also, THANK YOU A TON @donavon!

@donavon
Copy link
Contributor Author

donavon commented Jan 24, 2019

Of course @kentcdodds.

I think we should be ready to release testHook on the same day that 16.8.0 drops (i.e. ride the hype), which could be any day now.

I'll work to get things tied up with the PR. Then, when we're satisfied, I'll pre-update the dependencies to say 16.8.0. This will, of course, fail in Travis as there isn't a 16.8.0 today.

But the second 16.8.0 drops, all you have to do it re-run the job in Travis (it should pass, hopefully anyway 🤞) then merge the PR.

However, I'm on PTO starting Monday and don't think I'll have the time between now and then to write the useEffect example as I'm swamped with other stuff as well. Could this some at a later date or as a separate PR?

@alexkrolick
Copy link
Collaborator

But the second 16.8.0 drops, all you have to do it re-run the job in Travis (it should pass, hopefully anyway 🤞) then merge the PR.

facebook/react#14692

Better get this ready 🚦😉

@kentcdodds
Copy link
Member

That all sounds fine @donavon 👍

@donavon
Copy link
Contributor Author

donavon commented Jan 24, 2019

@alexkrolick 😱

NOTE: Travis should FAIL with this commit. Re-run the job when React 16.8.0 drops (soon).
@donavon
Copy link
Contributor Author

donavon commented Jan 24, 2019

dependencies updated and Travis build failed (as it should). with this, we should be ready to go! my work is done here. 😉

let me know if you need anything else.

Copy link
Collaborator

@antsmartian antsmartian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM..

@antsmartian
Copy link
Collaborator

@donavon Thank you so much for this PR. The code looks good to me, as Kent mentioned, we can fix some nits and get this asap when hooks are available! 👍

@alexkrolick
Copy link
Collaborator

We should check out the new test utils API in reactjs/react.dev#1629

@kentcdodds
Copy link
Member

The React team consulted with me about this. As soon as the new version lands I'll personally take on the work of updating things to work with hooks and their new APIs.

@alexkrolick
Copy link
Collaborator

Ok great @kentcdodds 👍

@kentcdodds kentcdodds changed the base branch from master to next February 5, 2019 22:31
@kentcdodds
Copy link
Member

Changed this to next branch so I can release this along with other changes to prepare for hooks.

@kripod
Copy link

kripod commented Jun 14, 2019

What happened to this feature? Unfortunately, I cannot find it anywhere...

@bcarroll22
Copy link
Contributor

👋 you’ll wanna check out react-hooks-testing-library if you’re testing custom hooks that you share between components.

Otherwise, testing hooks via user interactions like clicks, etc. works just like anything else would with this library.

Good luck!

@alexkrolick
Copy link
Collaborator

We should finish the PR to add that lib to the docs

@tomstuart
Copy link

@kripod Here’s the information you’re missing: #302

lucbpz pushed a commit to lucbpz/react-testing-library that referenced this pull request Jul 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants