So that's the first render. We make our assertion. Then we wait until we have a second element in the array, and we can make assertions on it. That's the nice thing, because if there was only one element, this will just throw and wait for it to continue repeating. In the end, we even wait like 100 milliseconds, and we make sure that there hasn't been another rerender in that time by just asserting on the length of render snapshots. This essentially does what we need, but honestly, it looks horrible, and I don't want to write at least two tests with that, and I need to write hundreds.
So in the end, we are library authors, so we know how to build a library, right? This is where we come to a little problem with this talk, because back when I submitted this talk, I called it Beyond Testing Library, but the reality is that by now, I'm introducing a new testing library. It's called Testing Library React Render Stream, and it's a new testing library based on that profiler component we saw before, but tacking it away so it doesn't annoy us anymore so we can test hot code paths reliably.
Let's get back to that test that we had earlier with a profiler and see how we can make that more readable. It starts by removing all of this weird wrapper, and the current results, and the render snapshots thing. We just move forward. We replace it with something easier, and we say, create render stream, and we get back an object that has at least a replace snapshot function and a render function. We can call that replace snapshot function in our component with the return value of use query, and then we call the render function, which is essentially the same render function with a few adjustments that we already know from testing library.
Now we have these assertions, the wait for us are not nice. Working with an error here is not nice, so how can we change this around? We take a take render function from our render stream, and that take render has the nice thing that it returns a promise of the next render, and the next render that will happen or already has happened. We can just step by step always call take render, and we will go through everything render by render by render. In this case, I'm using this notation with loan blocks, so I can reuse variable names so we don't have snapshot one, snapshot two, and snapshot three. We just say, we take the first snapshot, and we assert on it. We take the second snapshot, and we assert on it. That leaves us with this set timeout down here, which is also not nice, so let's replace that with something nicer. We can do expect take render, not to re-render. This has a default of 100 milliseconds, but you also can add an option and configure it. The last thing here is that react-testing-library also has a render hook, and we have this create render stream with a render call. We can make that simpler and if we use a render hook to a snapshot stream with a hook directly here and instead of having to take renders and take the snapshot out of the render, the snapshot is all we are ever interested in when we test for hooks. So here we can directly do take snapshot and use that. And that's actually a pretty nice test. So let's look back at the special requirements we had earlier. We had that component render count that we wanted to test for, and we can't do that. We can't test that no more renders happen. And for consistency testing, we can test the hook and we can test the component.
Comments