Best practice for creating an API resource in unit test – database or POST endpoint?

Issue

What is the best practice for creating resources while unit testing a GET endpoint in a REST API?

Should I create them directly in the database:

  def test_can_get_todos_list(self):

        todo1 = Todo(text='todo1', user_id=self.user.id)
        todo2 = Todo(text='todo2', user_id=self.user.id)

        db.session.add_all([todo1, todo2]) # creating expected response todos directly in the database
        db.session.commit()

        response = self.client.get('api/todos')
        result = [
            {'text': 'todo1', 'id': 1},
            {'text': 'todo2', 'id': 2},
        ]
        
        self.assertEqual(response.status_code, 200)
        self.assertEqual(result, response.json)

or should I utilize another API endpoint (POST) that I built for creating resources of this type. So instead of doing:

db.session.add_all([todo1, todo2]) 
db.session.commit()

I could do something like this:

self.client.post(/api/todos, data='todos payload here')

Solution

When testing the API as an integration test – i.e. as a completely external test – use the API for every part of the test. Having some parts use the API and some parts use the internal API will make the test more brittle (i.e. changes to either functionality might need updating the test).

Instead the test should use the API of the same abstraction level of the functionality that the tests implement. If you’re using the external API, you should use the external API for any feature of the tests. That will also allow you to run the tests externally from your own code, and they will serve as both documentation and examples of how to use the API.

Implementing the tests in this manner will also expose any shortcomings of the API; if you discover functionality that you can’t implement through the API but is required for writing the test, then you’ve found a use case that isn’t covered by your current API.

Many frameworks also feature dedicated test clients that sets up the test environment for you, so that the requests doesn’t have to actually set up a listening socket and run a http server. This speeds up the tests when testing the external API.

Answered By – MatsLindh

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published