3 ms·
I have adopted Prisma in my latest project and I have mixed feelings about it. - The generated client is top-tier. Fully specified in TypeScript with intellige
by CGamesPlay 6y ago
I have adopted Prisma in my latest project and I have mixed feelings about it.
- The generated client is top-tier. Fully specified in TypeScript with intelligent types that can be extended by the user.
- The schema language is great. It provides a cohesive experience that can fully express your database structure, and it also provides a migration framework to manage that structure's evolution.
- There's no hook for implementing access control at the model level, so you end up needing to create a higher-level API around the base queries to implement these yourself, which is a fairly large investment. I'd love to see a pair of functions that can modify the query before it gets sent to the Prisma engine to add extra query values, and a second function that can filter models before they are returned to the caller.
Where Prisma falls short is in testing. The testing story in Prisma is that you can either use a live database, or you can completely stub out all calls to Prisma in your application. The latter means you end up writing a bunch of tests for implementation rather than for behavior, or you end up manually writing an in-memory database that fits the Prisma API. The former means that you need to completely recreate your database after every test case.
The discussions on the Github seem to indicate that the old "wrap the test in a transaction" trick is forbidden, and Prisma seems architecturally set up to ensure that you can't even hack this behavior in.
All in all, we probably won't switch away from it, but I will continue to look for a better way to test my endpoints.
- agustif 6y agoHey totally off-topic maybe as it's not prisma-related/required. What do you think of using something like msw.io for mocking your endpoints as needed?
- tor291674 6y ago> msw.io The website is https://mswjs.io/ https://mswjs.io/
- kami8845 6y agoWhile depending on a live DB for testing isn't great, why not just blow away database state after every test by running TRUNCATE / DELETE against all tables? DELETE especially is very fast (couple ms) if you're not inserting large amounts of data during your test runs.
- molf 6y ago1) You can't run tests in parallel. 2) It is at least an order of magnitude slower than not using a database at all. Combined this makes for very slow tests. Certainly for larger applications with thousands of tests. Having said that, I don't think there is a single right answer to the problem of testing applications that use a database and your suggestion still can be a valid solution.
- megous 6y ago1) Actuallly you can, in multiple ways: - parallel sessions on one database just like multiple clients accessing your web app at the same time - create multiple copies of a schema and run different independent testusite legs on each (you just have to pass X-Test-Schema in the HTTP header to select on which schema should the web app operate) - I have an even better trick up my sleeve for testing an app with a real DB backend, and that's passing X-Test-Force-Time header that allows me to override time under which app and DB operates per-request, so I can test even time dependent behavior, like timeouts, timed queues and events, time dependent DB queries, etc. And in general just have a stable predicatble timestamps in the database for each test run and be able to compare database states at the end of the test run and check the diff for irregularities against the previous test runs, or known good state. I have to patch postgresql to allow for output of now() current_timestamp, etc. to be overridable per session, but it's absolutely worth it to be able to simulate/control the flow of time across the whole stack. You can actually do a lot of useful stuff with schemas and search_paths, without disrupting connected clients, and without having to re-create databases, all in a transactional/atomic manner, that is very useful for testing.
- pimeys 6y agoIf you run postgres, make a schema per test and do a cascading drop to the schema after the test. Name the schema either by the test or with a random string. Same applies for SQL Server and on MySQL you'd do this with databases instead. Parallelizes quite well when we test the engines at Prisma...
- matthewmueller 6y agoThanks for sharing your thoughts. The lack of Client extensibility is definitely a shortcoming right now. We're thinking of ways to wrap the Client a bit better. Middleware works is a decent workaround, but doesn't fit all these use cases. On testing, we're working on some documentation right now on how to mock the Prisma Client. I could see us generating a mockable client to help with this.
- mst 6y agoSpinning up a temporary e.g. postmaster instance for a test off a pre-built data directory (bonus: use zfs or btrfs or similar snapshots to make this even faster) is, IME, while still effectively "completely recreate" also both much more robust than wrap-in-transaction and generally not the slowest thing about your tests (and of course allows reliable parallelisation). Bit of setup effort but well worth it IME even in situations where your tooling isn't strongly pushing you towards the approach.