How I think about repositories:
These are simple wrappers around database calls that have few or no dependencies. If I'm adding dependencies here, then they'll either be a cache or a logger.
Make repositories as simple as possible, because texting them sucks. You make a repository because it makes unit testing your service easier.
How I think about services:
Services are just groups of related methods. In a simple CRUD API, I would typically do a service per controller and include all business logic at the service level.
How I think about controllers:
These should be treated like repositories and only contain logic for determining which response code to send.
The typical way to test a repository is to create an in memory database and manually load data into it.
This sucks.
If you directly use the dbcontext in your service layer, then you have to populate data for every edge case to test it.
Make a super simple repository with no logic, and you only need 1 test case per method. Then in your service layer you mock the repository and tell it to return any random object you need.