Unit test to get a blog

Git Commit: unit test to verify getting a blog
Let's write one more unit test to get more familiar with unit testing. Ideally, We should have 100% coverage and test each of our routes. However, unit tests just follow a pattern, if you understand the pattern you can write a unit test for all the routes on your own.
This time let's tackle the get_blog route. In order to test fetching a blog, we must first create a blog then only we can fetch the blog. However, in order to create a blog we need to create a user🀦!

Since the transactions are rolled back and even the database is truncated on each unit test. All our unit tests are independent of each other. The user that we created in our last tutorial for the unit test of create_user route, no longer exists. Let's write some utility functions to create a random user and a random blog.

πŸ“ backend/
β”œβ”€πŸ“„ .env
β”œβ”€πŸ“„ .env.example
β”œβ”€πŸ“ alembic/
β”œβ”€πŸ“„ alembic.ini
β”œβ”€πŸ“ apis/
β”œβ”€πŸ“ core/
β”œβ”€πŸ“ db/
β”œβ”€πŸ“„ main.py
β””β”€πŸ“„ requirements.txt
β”œβ”€πŸ“ tests/
β”‚ β”œβ”€πŸ“„ conftest.py
β”‚ β””β”€πŸ“ test_routes/
β”‚   β”œβ”€πŸ“„ test_blog.py    #new
β”‚   β”œβ”€πŸ“„ test_user.py
β”‚ β””β”€πŸ“ utils/
β”‚   β”œβ”€πŸ“„ blog.py         #new
β”‚   β”œβ”€πŸ“„ user.py         #new

In the file named tests > utils > user.py, We need to put the logic to create a new random user. We can utilize the repository to create a new user.

from sqlalchemy.orm import Session
from db.repository.user import create_new_user
from schemas.user import UserCreate


def create_random_user(db: Session):
    user = UserCreate(email="[email protected]",password="Hello!")
    user = create_new_user(user=user, db=db)
    return user

This handles the responsibility of creating a new user and returning it, we can utilize this method in creating a new random blog at tests > utils> blog.py

from sqlalchemy.orm import Session
from db.repository.blog import create_new_blog
from schemas.blog import CreateBlog
from tests.utils.user import create_random_user


def create_random_blog(db: Session):
    blog = CreateBlog(title="first_blog", content="Tests make the system stable!")
    user = create_random_user(db=db)
    blog = create_new_blog(blog=blog, db=db, author_id=user.id)
    return blog

Now, we are good to create a test that fetches a blog from the get_blog() route.

from tests.utils.blog import create_random_blog


def test_should_fetch_blog_created(client, db_session):
    blog = create_random_blog(db=db_session)
    # print(blog.__dict__)    #use pytest -s to see print statements
    response = client.get(f"blog/{blog.id}/")
    assert response.status_code == 200
    assert response.json()["title"] == blog.title

Now, if you type in pytest. You should see 2 tests passing.

(env) C:\Users\nofoobar\fastapi-blog\backend > pytest
=================================================================== test session starts ===================================================================
platform win32 -- Python 3.9.6, pytest-7.4.0, pluggy-1.2.0
rootdir: C:\Users\nofoobar\fastapi-blog\backend
plugins: anyio-3.7.0
collected 2 items

tests\test_routes\test_blog.py .                                                                                                                     [ 50%]
tests\test_routes\test_user.py .                                                                                                                     [100%]

======================= 2 passed in 1.03s =======================

In case you want to debug a test, you can put some print statements and type pytest -s, this lets pytest know that it has to be verbose and show the output of print statements to stdout.

FastAPITutorial

Brige the gap between Tutorial hell and Industry. We want to bring in the culture of Clean Code, Test Driven Development.

We know, we might make it hard for you but definitely worth the efforts.

Contacts

Refunds:

Refund Policy
Social

Follow us on our social media channels to stay updated.

Β© Copyright 2022-23 Team FastAPITutorial