4 ms·
Honestly, just use a real db in testing. Purity is all well and good, but not at the expense of more bugs caught.
by vasachi 3y ago
Honestly, just use a real db in testing. Purity is all well and good, but not at the expense of more bugs caught.
- DarkNova6 3y agoSometimes you don’t have that option. Or the database has so many constraints that creating testdata is just not worth the mountain of effort. Imho: Everything which promotes unit testing also promotes maintainable code.
- MoreQARespect 3y agoDependency inversion with the aim of writing unit tests is helpful for logic or calculation heavy chunks of code but for everything else it actually makes the code less maintainable. It balloons the size of the code base and as a reward you end up with a ton of mimetic tests that mirror the code and dont actually catch any bugs.
- DarkNova6 3y agoI'm sure this approach can be applied to some problem domains better than others. If you have a simple CRUD app, then yes there isn't much you can check. But even there, you can at the very least mock the responses of the database (or other external systems) and check if the data in your response is as expected. Naturally, this works best if you work with structured data or have a well-defined domain. In case of a well defined domain, you can just mock the domain models don't even touch the module which talks to the outside world.
- MoreQARespect 3y ago>But even there, you can at the very least mock the responses of the database (or other external systems) and check if the data in your response is as expected. You certainly can but these tests end up mimicking the implementation rather than actually testing the code. A pure CRUD app - even if it's relatively complicated - should have zero unit tests.
- DarkNova6 3y agoI guess you can technically test everything in a CRUD app as integration test. Doesn't mean you should. Surely, you have a baseline of verification/validation logic for which unit tests are the best fit. And based on my experience of my last project, if you can't do proper unit testing you likely have the wrong granularity in your methods and classes.
- puika 3y agoI also don't see the point in mocking out your database unless you have slow tests due to hardware constraints, a huge project or your db tests not being parallelized. Regarding the latter I've had much success with a similar approach to [1], and with a few helpers in each layer (service-repo) my tests have never been cleaner. [1]: https://kevin.burke.dev/kevin/fast-parallel-database-tests https://kevin.burke.dev/kevin/fast-parallel-database-tests
- quectophoton 3y agoSame. The moment my tests need to care about implementation details, is the moment I stop trying to mock/fake/stub/etc stuff and just test against the real thing if possible. I don't want to worry about whether a library is correctly implementing the real behavior of the real thing. I can understand wanting to mock/fake/stub/whatever stuff that is outside of your control, like a third-party HTTP API where you can't just send real requests just for testing. But for the situation in the article, those tests just seem too fragile to me. And a lot of effort for the comparatively little confidence added by the test results.
- marvinblum 3y agoI keep wondering why people won't test with a real database. Right, you need to create it and clean it up before or after every test, but that's a lot cheaper than having to stub everything related to the db. Also spinning one up locally is easy thanks to Docker.
- drewcoo 3y agoIf you're using a container, you don't need to create the DB or clean it up when you run tests. Just spin up a new container and then throw it away if nothing went wrong.
- patmorgan23 3y agoCreate = spin up Clean up = throw away
- masklinn 3y ago> Right, you need to create it and clean it up before or after every test, but that's a lot cheaper than having to stub everything related to the db. Depends on the bringup cost, although templates help there (create a baseline database, then copy it for each test).
- horeszko 3y agoDocker is great, another option I like to use is sqlite. I'm writing a small and simple application and I'm just using an sqlite database for my tests. I have a helper function to create the db, another to add a table, and then a third to delete the db at the end. So in total 3 functions to setup and teardown a test database. Its super quick because an sqlite db is just a file after all.
- rswskg 3y agoit's a real shame that sqlite and postgres have sql differences, otherwise I'd use it alot more
- islon 3y agoYeah... Mocking is like wanting to be a lion tamer but training with a cat.