The lower level tests we can write are called unit tests. They should test a small portion of code, hence the notion of unit. How you define a unit is up to you; it can be a class or a bunch of closely related classes. Defining this notion will determine what will be mocked (replaced with a dummy object). Are you going to replace the database with a lightweight alternative? Are you going to replace interactions with external services? Are you going to mock-up closely related objects whose behavior is not relevant to the context of what's being tested?
My advice here is to keep a balanced approach. Keep your tests clean and fast, and everything else will follow.
I rarely completely mock the data layer. I tend to use embedded databases for testing. They provide an easy way to load data while testing.
As a rule, I always mock collaboration with external services for two reasons, as follows:
The speed of the tests and the possibility to run the tests without connecting to the network...