Live data from Hacker News

Database mocks are not worth it

shayon.dev

201–210 of 268 posts

Re: Database mocks are not worth it

#201

Earlier quoted context omitted.

The imperative shell is untestable with unit tests. You don’t test it this way period. Think about it. This IO layer should be so thin that all you’re doing is fetching and getting so this layer does a direct external call. When you mock this entire thing is basically what is mocked. So if you mock or don’t mock if you write your code with the pattern of functional core and imperative shell the imperative shell is wh…

> whats the point? suppose you are writing some software that interfaces with personal finance SAAS. except you want your users to be able to interact with more than one. so you sure as shit better be testing that your abstractions are making the correct calls, especially if customer money is involved. you also really want to be testing for unreliability, for example, if your saas call is taking too long, you dont do…

No. You completely missed what I said. I differentiated between unit tests and integration tests. Your imperative shell is not testable in the context of unit tests. However you must test it via integration tests.

Mocks are a utility for unit tests hence the topic of this post. We are talking about unit tests and mocking aspects of the unit test that can’t be tested via unit tests.

Integration tests are another topic. With integration tests or end to end tests you test everything. You don’t mock. Mocking is not really a valid concept in the context of integration tests.

Re: Database mocks are not worth it

#202

Don’t code with mocks period. Structure your code such that it has a functional core and imperative shell. All logic is unit testable (functional core). All IO and mutation Is not unit testable (imperative shell). Mocks come from a place where logic is heavily intertwined with IO. It means your code is so coupled that you can’t test logic without touching IO. IO should be a dumb layer as much as possible. It should b…

I haven't seen the "stored procs only"-style of DB development since the early 2000's, and I'd never go back to that.

Re: Database mocks are not worth it

#203

Earlier quoted context omitted.

Is this about having application logic in multiple places, or having application logic co-located with the data? Does it make a difference if the procedures are database triggers vs being directly called by the application code? Would splitting off some of the logic into a separate service (that does its own database accesses) have the same issues?

Say I have functionality to get customer data. If the sql logic is in code, I can create a new branch and work on it, merge my changes, I can do blue/green deployments. A rollback if you’re using Kubernetes is a simple matter of reverting back to the configuration file containing a reference to the old Docker container etc. How do you roll back a dozen stored procedures quickly? How do you just create a new branch or…

In your post you talk about forking and rolling back.

I bet the same can be done for SP, even if is a fork and add suffix approach

The calling code can call either

On a phone hope I’m clear enough

Re: Database mocks are not worth it

#204

Earlier quoted context omitted.

My current setup on a personal project is docker compose with Postgres and pgadmin container. I would never think of mocking a database in 2024/2025, just spin one up. Also keep your lynch pin invariants in the database and not in your code.

in 2024/2025 you just might be working with 985 petabyte database which just might have a few issues being “spun up” :)

Are you developing directly against your production database?

Re: Database mocks are not worth it

#205

Earlier quoted context omitted.

in 2024/2025 you just might be working with 985 petabyte database which just might have a few issues being “spun up” :)

Are you developing directly against your production database?

replica in the staging environment

Re: Database mocks are not worth it

#206

Earlier quoted context omitted.

Say I have functionality to get customer data. If the sql logic is in code, I can create a new branch and work on it, merge my changes, I can do blue/green deployments. A rollback if you’re using Kubernetes is a simple matter of reverting back to the configuration file containing a reference to the old Docker container etc. How do you roll back a dozen stored procedures quickly? How do you just create a new branch or…

In your post you talk about forking and rolling back. I bet the same can be done for SP, even if is a fork and add suffix approach The calling code can call either On a phone hope I’m clear enough

If I need to fork code am I going to then make copies of all of the stored procedures corresponding with the code and now have getCustomer1, getCustomer2… and doing the same with all of your procedures?

And then do I need to change all of my stored procedure references in my code? Do I merge my changes back to the main one when done?

Isn’t just doing a “git branch” easier?

Rolling back, is just doing a git revert in your separate Kubernetes repository (you are doing proper Gitops aren’t you?), recommitting your code and your cluster is now using your old Docker container.

If you aren’t using K8s, you just push your old code.

Re: Database mocks are not worth it

#207

Earlier quoted context omitted.

Is this about having application logic in multiple places, or having application logic co-located with the data? Does it make a difference if the procedures are database triggers vs being directly called by the application code? Would splitting off some of the logic into a separate service (that does its own database accesses) have the same issues?

Say I have functionality to get customer data. If the sql logic is in code, I can create a new branch and work on it, merge my changes, I can do blue/green deployments. A rollback if you’re using Kubernetes is a simple matter of reverting back to the configuration file containing a reference to the old Docker container etc. How do you roll back a dozen stored procedures quickly? How do you just create a new branch or…

> How do you roll back a dozen stored procedures quickly?

Liquibase rollback feature. The SQL changesets and rollback strategy is all defined in my .sql liquibase files and goes inside my git repo alongside my scala/python code the associated CICD automated integration tests + deployments.

Blue Green deployment can handled via bidirectional active-active database replication across your two disaster recovery databases; you deploy the newer stored procedures on one but not the other. Or you have sharded databases for some but not all customers and deploy blue/green with appropriate blue/green sharding. Or you could have separate version numbers for the stored procedure names (perhaps with a wrapper stored procedure that works differently on different shards/databasenames to isolate the impact from your non-SQL codebase.) Or just put a form of feature flags in your stored procedures; it's not 100% blue green but with minor integration test coverage it can be quite safe and allow you to run two code bases at once even in a single database.

Agree with you on triggers (and I agree to a point that stored procedures are often not the right approach despite my above rebuttal... but it is quite straightforward with the right tooling/mindset. For high-volume analytics with aggregations you might be better off leaving the data in columnar database SQL and doing some stored procedures if the code was complex enough; but for CRUD apps I would strongly discourage stored procedures.)

Re: Database mocks are not worth it

#208

Earlier quoted context omitted.

Transaction per test is how that works in ruby on rails. Also, the rspec parallel gem will create N test databases for running tests - one per process.

That doesn't work if you need to commit for one reason or an other. And while in some cases you might be able to substitute subtransactions via some sort of test mode, it's not always an option depending what you're doing / testing exactly.

Nested transactions handle commits. At the beginning of a test, a new transaction is begun, and it is rolled back at the end of the test. As others have pointed out in this discussion, it's pretty standard with Ruby on Rails apps, especially those which use rspec for testing.

Re: Database mocks are not worth it

#209
post #146

Earlier quoted context omitted.

How do you write the expected return from an external API in your test setup?

That’s an integration test. Your external api returns a number, let’s say 10. You have two local functions. One that is very general and fetches that number, and another that transforms that number. Your local transformation function is the one that is tested. The other function is part of integration tests and in general can’t be unit tested.

Exactly, there's a layer (integration testing) where I usually do need to have a test against a mock to validate my function doing the external call is passing a request I expect. I can break it down into a parameter supplier function that will generate the proper request params and test that but I don't see any gain in abstracting that away simply to avoid mocks.

Re: Database mocks are not worth it

#210

Don’t code with mocks period. Structure your code such that it has a functional core and imperative shell. All logic is unit testable (functional core). All IO and mutation Is not unit testable (imperative shell). Mocks come from a place where logic is heavily intertwined with IO. It means your code is so coupled that you can’t test logic without touching IO. IO should be a dumb layer as much as possible. It should b…

I haven't seen the "stored procs only"-style of DB development since the early 2000's, and I'd never go back to that.

Lambda functions would like to have a word...
Post reply on HN