When writing tests for my FastAPI endpoints I am not sure which is the best way to setup the test (store data in the DB, prepare data for the body of a POST call, etc.).

I can either use:

  • direct calls to the DB to set it up (SQL)
  • methods from my Repositories (Repository Pattern)
  • other endpoints to get tokens, prepare the DB, and so on.

After doing the above cases, I can finally call the endpoint I'm testing and see if I get the error codes, response messages, data, that I expect.

Using SLQ (or an ORM) to setup the test feels problematic, since I have to replicate complex queries, effectively 'copying' code from the Repositories. Using other endpoints has the drawback that my tests are dependent on code that they aren't testing (it does however make some tests shorter). Or should I mix high level and low level code to do the test setup?

Picture below summarizes the question:

enter image description here


1 Answer 1


I think the problem is that "testing endpoints" is the wrong way to think about what you're doing.

You need to have a clear concept of what you're testing:

  • If it's a real integration test, you don't test "endpoints" but the system as a whole and how its parts integrate with each other. That means you definitely want to set up your data using other endpoints. The problem with using SQL or ORM is not so much that you're replicating queries, it's that this replicated logic can be subtly different from what the real system will do, which can lead to the tests failing to expose bugs. The goal of integration tests is to catch exactly those bugs that arise from the interaction of the system's components as they will run when it's deployed. You're not going to be able to exhaustively test all edge cases here simply because it would take too long.
  • If you're unit testing, you don't test "endpoints", but the code that handles HTTP requests. Which means you actually don't want to involve your DB at all, and maybe not even your service layer (i.e. the code that is more concerned with the business objects rather than HTTP requests). Instead, you'll use a mocking framework to produce the data for the HTTP-request-handling code to return. The goal of unit tests is to make it easy and fast to exhaustively test edge cases that can be slow and difficult (even impossible) to test with integration tests.

It's possible to have tests that are somewhat inbetween these poles, but if you're doing that, you should be able to articulate a reason for it, and that reason should then guide your choice in how to set up your test data.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.