DEV Community

Discussion on: "I need to change this code, but it has no test"

Collapse
 
lexlohr profile image
Alex Lohr

I would disagree on the assertion that snapshots had few valid use cases.

First of all, their most valuable effect is to make changes visible. However, you need to review those changes to make use of the snapshot.

Then, in many cases, you'll expect some more complicated object to be returned. While you can write down that object in the test and handle each necessary change manually, you can let snapshots do that for you to the same effect.

Especially for test driven development, having the difference in output easily visible is a good way to verify the incremental changes with less work than you'd otherwise have. Obviously, the snapshot is then but a supplement to an actual test, but it will ease your work nevertheless.

Collapse
 
nicoespeon profile image
Nicolas Carlo

Hi Alex!

I don't see how you could TDD (as "write the test before changing the code") using snapshots. Do you have an example in mind?

Concerning complex objects, snapshots can be really handy indeed. Though, I would first ask myself:

  • Is my test actually testing the complete object? If I only care about some properties, I can use Jest's toMatchObject() for example.
  • Can I change the design so it's not that complex to write the expected object first? It really depends on what kind of object we're dealing with
  • Can I refactor my tests so it's not that difficult to see the expected changes? I might come up with a factory, for example.

But this often happens to me when I didn't write the tests first and I'm working with existing code, which is complex. I also realize that if it's complex for me to use in tests, it might be complex for other consumers of this code to reason about/use.

Although, I do use snapshots in such cases too:

  • either because it's code that didn't have tests in the first place, and I don't have time to write them by hand (which is more or less the scenario I described here)
  • either because we're dealing with UI tests (e.g. testing the rendered React view)

Either way, snapshots are "anti-regression" tests. Which is a valuable tool that I like to have. But when possible (and relevant), I try to think about what I want the code to do and I write an automated test first.

Collapse
 
lexlohr profile image
Alex Lohr

You can actually write the snapshot itself as if it was code. The main advantage over toMatchObject(...) is that you can also use property matches like Any<Date> in there.

Thread Thread
 
nicoespeon profile image
Nicolas Carlo

Oh, I see! Indeed, that's an interesting way to do, thanks for sharing 😃

I wonder though: couldn't you use expect.any(…) to achieve the same, in your test code instead?

Thread Thread
 
lexlohr profile image
Alex Lohr

Not sure. Let me test later, have a bunch of meetings ahead now.

Thread Thread
 
lexlohr profile image
Alex Lohr

It actually seems to work.