Skip to content

Commit

Permalink
테스트코드 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
riroan committed Aug 24, 2024
1 parent 95c5613 commit 6b84202
Show file tree
Hide file tree
Showing 15 changed files with 416 additions and 8 deletions.
5 changes: 4 additions & 1 deletion app.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
from presentation.like import api as like_api
from presentation.ping import api as ping_api
from presentation.product import api as product_api
from settings import Settings


def create_app():
def create_app(settings: Settings):
app = FastAPI()

app.add_middleware(
Expand All @@ -20,6 +21,8 @@ def create_app():
allow_headers=["*"],
)

app.settings = settings

app.add_exception_handler(BaseException, handle_exception)

app.include_router(like_api)
Expand Down
2 changes: 1 addition & 1 deletion db.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def __init__(self, settings: Settings):
database=settings.db_name
)
self.engine = create_engine(
url=url, echo=True
url=url
)
self.session = sessionmaker(
autocommit=False,
Expand Down
6 changes: 3 additions & 3 deletions depends.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from typing import Annotated

from fastapi import Depends
from fastapi import Depends, Request

from db import Database
from settings import Settings


async def get_settings() -> Settings:
return Settings()
async def get_settings(request: Request) -> Settings:
return request.app.settings


async def get_database(
Expand Down
3 changes: 2 additions & 1 deletion main.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from app import create_app
from settings import Settings

app = create_app()
app = create_app(Settings())
2 changes: 1 addition & 1 deletion presentation/cart.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ async def update_shoppingcart(
cart: CartUpdateDto,
session: Annotated[Session, Depends(get_session)]
) -> CartUpdateDto:
await update_shoppingcart(cart_id, cart, session)
await cart_service.update_shoppingcart(cart_id, cart, session)

return cart

Expand Down
3 changes: 3 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# pytest.ini
[pytest]
asyncio_default_fixture_loop_scope = session
1 change: 1 addition & 0 deletions service/cart.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from sqlalchemy.orm.session import Session

from dto.cart import CartDto, CartUpdateDto
from exception import BadRequestException, NotFoundException
from orm.cart import Cart
Expand Down
3 changes: 2 additions & 1 deletion service/like.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@


from sqlalchemy.orm.session import Session

from const import LikeStatus
from dto.like import LikeDto
from orm.like import Like
from sqlalchemy.orm.session import Session
from repository.like import LikeRepository


Expand Down
5 changes: 5 additions & 0 deletions settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@ class Settings(BaseSettings):
db_password: str
db_host: str
db_port: int


class TestSettings(Settings):
db_port: int = 9999
db_name: str = "test"
126 changes: 126 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import pytest
import pytest_asyncio
from sqlalchemy import URL, create_engine
from sqlalchemy.orm import sessionmaker

from app import create_app
from const import LikeStatus
from orm.base import Base
from orm.cart import Cart
from orm.like import Like
from orm.product import Product
from orm.user import User
from settings import TestSettings
from tests import helper


@pytest_asyncio.fixture(scope="session")
async def settings():
return TestSettings()


@pytest_asyncio.fixture(scope="session")
async def test_fastapi_app(settings):
return create_app(settings)


@pytest_asyncio.fixture(scope="function")
async def engine(settings):
url = URL.create(
drivername="mysql+pymysql",
username=settings.db_user,
password=settings.db_password,
host=settings.db_host,
port=settings.db_port,
database=settings.db_name
)
eng = create_engine(
url=url
)
Base.metadata.create_all(eng)
yield eng
Base.metadata.drop_all(eng)


@pytest_asyncio.fixture(scope="function")
async def session(engine):
sessionLocal = sessionmaker(engine)
return sessionLocal()


@pytest_asyncio.fixture(scope="function")
async def user():
return [
User(
id=1,
email=helper.TEST_USER_EMAIL_1,
password=helper.TEST_USER_PASSWORD_1
),
User(
id=2,
email=helper.TEST_USER_EMAIL_2,
password=helper.TEST_USER_PASSWORD_2
)
]


@pytest_asyncio.fixture(scope="function")
async def product():
return [
Product(
id=1,
name=helper.TEST_PRODUCT_NAME_1,
image_path=helper.TEST_PRODUCT_IMAGE_PATH_1,
price=helper.TEST_PRODUCT_PRICE_1,
summary=helper.TEST_PRODUCT_SUMMARY_1
),
Product(
id=2,
name=helper.TEST_PRODUCT_NAME_2,
image_path=helper.TEST_PRODUCT_IMAGE_PATH_2,
price=helper.TEST_PRODUCT_PRICE_2,
summary=helper.TEST_PRODUCT_SUMMARY_2
)
]


@pytest_asyncio.fixture(scope="function")
async def shopping_cart():
return [
Cart(
id=1,
user_id=1,
product_id=1,
count=5
)
]


@pytest_asyncio.fixture(scope="function")
async def like():
return [
Like(
id=1,
is_like=LikeStatus.DISLIKE,
user_id=1,
product_id=1
)
]


@pytest_asyncio.fixture(scope="function")
async def bootstrap(
session,
user,
product,
shopping_cart,
like,
):
session.bulk_save_objects(user)
session.bulk_save_objects(product)
session.bulk_save_objects(shopping_cart)
session.bulk_save_objects(like)

session.commit()

yield "bootstrap"
131 changes: 131 additions & 0 deletions tests/e2e/test_cart.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import pytest
from fastapi import status
from httpx import ASGITransport, AsyncClient

from tests import helper


@pytest.mark.asyncio
async def test_list_shoppingcart_returns_200(
test_fastapi_app, bootstrap, shopping_cart
):
async with AsyncClient(
transport=ASGITransport(app=test_fastapi_app), base_url="http://test"
) as client:
response = await client.get("/cart/1")

assert response.status_code == status.HTTP_200_OK

result = response.json()
assert len(result["products"]) == len(
[i for i in shopping_cart if i.user_id == 1]
)


@pytest.mark.asyncio
async def test_add_shoppingcart_returns_201(
test_fastapi_app, bootstrap
):
async with AsyncClient(
transport=ASGITransport(app=test_fastapi_app), base_url="http://test"
) as client:
response = await client.post(
"/cart",
headers={
"Content-Type": "application/json"
},
json={
"user_id": 1,
"product_id": 2
}
)

assert response.status_code == status.HTTP_201_CREATED


@pytest.mark.asyncio
async def test_update_shoppingcart_returns_202(
test_fastapi_app, bootstrap
):
async with AsyncClient(
transport=ASGITransport(app=test_fastapi_app), base_url="http://test"
) as client:
response = await client.put(
"/cart/1",
headers={
"Content-Type": "application/json"
},
json={
"count": 123
}
)

assert response.status_code == status.HTTP_202_ACCEPTED


@pytest.mark.asyncio
async def test_update_shoppingcart_returns_400_when_invalid_count(
test_fastapi_app, bootstrap
):
async with AsyncClient(
transport=ASGITransport(app=test_fastapi_app), base_url="http://test"
) as client:
response = await client.put(
"/cart/1",
headers={
"Content-Type": "application/json"
},
json={
"count": 0
}
)

assert response.status_code == status.HTTP_400_BAD_REQUEST


@pytest.mark.asyncio
async def test_update_shoppingcart_returns_404(
test_fastapi_app, bootstrap
):
async with AsyncClient(
transport=ASGITransport(app=test_fastapi_app), base_url="http://test"
) as client:
response = await client.put(
"/cart/-1",
headers={
"Content-Type": "application/json"
},
json={
"count": 123
}
)

assert response.status_code == status.HTTP_404_NOT_FOUND


@pytest.mark.asyncio
async def test_delete_shoppingcart_returns_204(
test_fastapi_app, bootstrap
):
async with AsyncClient(
transport=ASGITransport(app=test_fastapi_app), base_url="http://test"
) as client:
response = await client.delete(
"/cart/1",
)

assert response.status_code == status.HTTP_204_NO_CONTENT


@pytest.mark.asyncio
async def test_delete_shoppingcart_returns_404(
test_fastapi_app, bootstrap
):
async with AsyncClient(
transport=ASGITransport(app=test_fastapi_app), base_url="http://test"
) as client:
response = await client.delete(
"/cart/-1",
)

assert response.status_code == status.HTTP_404_NOT_FOUND
43 changes: 43 additions & 0 deletions tests/e2e/test_like.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import pytest
from fastapi import status
from httpx import ASGITransport, AsyncClient


@pytest.mark.asyncio
async def test_like_returns_201(
test_fastapi_app, bootstrap
):
async with AsyncClient(
transport=ASGITransport(app=test_fastapi_app), base_url="http://test"
) as client:
response = await client.post(
"/like",
headers={
"Content-Type": "application/json"
},
json={
"user_id": 2,
"product_id": 1
}
)
assert response.status_code == status.HTTP_201_CREATED


@pytest.mark.asyncio
async def test_dislike_returns_201(
test_fastapi_app, bootstrap
):
async with AsyncClient(
transport=ASGITransport(app=test_fastapi_app), base_url="http://test"
) as client:
response = await client.post(
"/dislike",
headers={
"Content-Type": "application/json"
},
json={
"user_id": 2,
"product_id": 1
}
)
assert response.status_code == status.HTTP_201_CREATED
Loading

0 comments on commit 6b84202

Please sign in to comment.