Test against what won't change
When we write tests, we've inevitably got to choose an interface to write against - for a unit test, this is the interface of whatever unit is under test, usually the type signature of a function or the public methods on a class. These unit interfaces tend to change often in response to refactoring, optimisations, new requirements and so on, and they should be able to change quickly too, or we make any of these important improvements.
Instead what we want to do is write our tests against interfaces that seldom change, and thus we should target public, external interfaces, which are (generally) better designed and much slower to change than the non-exposed interfaces on units. For example, in our scenario above, we could treat our system as a black box and use its HTTP API as the interface that we use to test it (e.g. using supertest), use a mocked HTTP API for the web service it calls (e.g. using nock), and run it against a real database that we reset after each test.
Source: Test against what won't change, an article by Alex Gilleran.