-
Notifications
You must be signed in to change notification settings - Fork 234
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
Capture intermediate updates when hook rerenders #461
Comments
It's not the prettiest, but you can do something like this test('should capture all renders states of hook', () => {
const results = [];
const { result } = renderHook(() => {
const counter = useCounter();
results.push(counter);
return counter;
});
expect(result.current).toBe(1);
expect(results[0]).toBe(0);
expect(results[1]).toBe(1);
expect(results.length).toBe(2);
}) I wonder how common needing the intermediate states of a hook's render cycle is in general. Part of me feels like in the common case this is an implementation detail and testing for it will lead to brittle tests that break with every change to the hook's implementation, but for cases like this, where you want to write a test to prove an actually observed bug is now fixed, I feel like I want to provide better support for you. I don't think it would be difficult for us to keep all render results in an array and surface it in the results container as something like Happy to hear feedback from anyone on this. |
FWIW, I had a bit of a play and it's a relatively small change required to get this test to pass: import { renderHook } from 'src'
describe('result history tests', () => {
let count = 0
function useCounter() {
const result = count++
if (result === 2) {
throw Error('expected')
}
return result
}
test('should capture all renders states of hook', () => {
const { result, rerender } = renderHook(() => useCounter())
expect(result.current).toEqual(0)
expect(result.previous).toEqual([])
expect(result.all).toEqual([0])
rerender()
expect(result.current).toBe(1)
expect(result.previous).toEqual([0])
expect(result.all).toEqual([0, 1])
rerender()
expect(result.error).toEqual(Error('expected'))
expect(result.previous).toEqual([0, 1])
expect(result.all).toEqual([0, 1, Error('expected')])
rerender()
expect(result.current).toBe(3)
expect(result.previous).toEqual([0, 1, Error('expected')])
expect(result.all).toEqual([0, 1, Error('expected'), 3])
})
}) I'm still not sure it's a good idea. I also don't think we would provide both |
+1 on this - I often want to test the initial behavior of a hook before any rerendering, especially since this can be used to test SSR behavior. |
@sarahatwork thanks for your input. I had not thought of this as being a solution to testing SSR behaviour, which is an interesting thought as I just closed #387 tonight because it wasn't really going anywhere. What are your thoughts in regards to |
@mpeyper |
Alternatively, something like Also a +1 on this, for similar reasons as the parent. We have a hook where the output is related to the input in some way, and when it is out of sync the component would cause errors. Below I show a "faulty" implementation which we currently can't write tests for to guard against.
|
I've pushed up what I've got so far as a PR if anyone wants to continue it from here. Functionally I think it's fine, but it will need some documentation updates before it can be merged. I'm also happy if anyone want to have a go with their own implementation as well. |
feat: Capture all results a rendered hook produces as `result.all` Fixes #461 Co-authored-by: Josh Ellis <joshua.ellis18@gmail.com>
🎉 This issue has been resolved in version 3.6.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
What is your question:
Let's consider the following hook
when running a test using RHTL, the following passes:
But this test does not capture the actual behavior of how a component consumes a hook during different render cycles
Is there a way to test the output of the first render using RHTL? I'm currently in a situation where I just fixed a bug related to variable initialization in a custom hook and it would be nice to be able to add a test to increase my code coverage.
The text was updated successfully, but these errors were encountered: