My view tends to be that you only need to mock something that performs I/O, so I’d mock the database but I wouldn’t bother setting up mocks for anything else, or designing the structure around loose coupling.
When it comes to mocking, I’ve tended to use protocols around the database, based on the idea that’s a fast mechanism for polymorphism that allows multiple functions to be grouped together.