模拟问题:在本地工作但在 CI/CD 管道中失败

Mocking Issue: Working Locally but Failing in CI/CD Pipeline

提问人:user2325446 提问时间:11/15/2023 最后编辑:user2325446 更新时间:11/16/2023 访问量:30

问:

在 FAST API 中完成的 API 我收到错误:“无法连接到管道中'localhost'上的MySQL服务器,但不应该,因为我正在用魔术模拟连接。这些测试在我的本地机器上完美运行。

这是我 main.py


from fastapi import Depends, FastAPI
from fastapi.middleware.cors import CORSMiddleware
from typing import Annotated
from data.database import engine,SessionLocal
from data.models import Base
from sqlalchemy.orm import Session 
from routers import contacts, users

app = FastAPI()
Base.metadata.create_all(bind=engine)

def get_db():
    db=SessionLocal()
    try:
        yield db
    finally:
        db.close()

db_dependency=Annotated[Session,Depends(get_db)]
# Configure CORS to allow requests from your Angular frontend


origins = ["*"]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
app.include_router(contacts.router, prefix="/contacts", tags=["Contacts"])
app.include_router(users.router, prefix="/users", tags=["Users"])

@app.get("/health" ,tags=['Health'])
async def check_health():
    return {"Hello": "World"}

   


Conftest:

from unittest.mock import MagicMock
import pytest 
from main import app
from routers.contacts import get_db


mock_session=MagicMock()

def override_get_db():
    try:
        yield mock_session
    finally:
        pass

app.dependency_overrides[get_db] =  override_get_db

@pytest.fixture
def mock_db_session():
    return mock_session

我的测试:



from unittest.mock import MagicMock, patch
from data.models import Contact
from fastapi.testclient import TestClient
from routers.contacts import get_db
from main import app


client = TestClient(app)


def test_create_contact(mock_db_session):
    url="/contacts"
    contact={"first_name":"Giovanni",
             "last_name":"Rossi",
             "email":"[email protected]",
             "phone_number":"1234567890" ,
             "user_id":1
             }

    response = client.post(url, json=contact)

    assert response.status_code == 201
    data = response.json()
    assert data["first_name"] == "Giovanni"
    assert data["last_name"] == "Rossi"
    assert data["phone_number"] == "1234567890"
    assert data["email"] == "[email protected]"


    mock_db_session.add.assert_called_once()
    mock_db_session.commit.assert_called_once()
    mock_db_session.refresh.assert_called_once()

def test_create_without_user_id(mock_db_session):
    url="/contacts"
    contact={"first_name":"Giovanni",
             "last_name":"Rossi",
             "email":"[email protected]",
             "phone_number":"1234567890" ,
             }

    response = client.post(url, json=contact)
    assert response.status_code == 422

def test_create_without_phone_number(mock_db_session):
    url="/contacts"
    contact={"first_name":"Giovanni",
             "last_name":"Rossi",
             "email":"[email protected]",
             "user_id":1
             }

    response = client.post(url, json=contact)
    assert response.status_code == 422

def test_get_contacts(mock_db_session):

    mock_query = MagicMock()
    mock_query.filter.return_value.all.return_value = [
    {
        "last_name": "Rossi",
        "id": 68,
        "phone_number": "1234567890",
        "email": "[email protected]",
        "user_id": 1,
        "first_name": "Giovanni"
    }
    ]

    mock_db_session.query.return_value = mock_query

    app.dependency_overrides[get_db] = lambda:mock_db_session
    response = client.get("/contacts/1")
    assert response.status_code == 200
    assert response.json() == [
    {
        "last_name": "Rossi",
        "id": 68,
        "phone_number": "1234567890",
        "email": "[email protected]",
        "user_id": 1,
        "first_name": "Giovanni"
    }
    ]

def test_get_empty_contacts(mock_db_session):

    mock_query = MagicMock()
    mock_query.filter.return_value.all.return_value = []

    mock_db_session.query.return_value = mock_query

    app.dependency_overrides[get_db] = lambda:mock_db_session
    response = client.get("/contacts/1")
    assert response.status_code == 200
    assert response.json() == []


  

platform darwin -- Python 3.10.9, pytest-7.1.2, pluggy-1.0.0 插件:anyio-3.7.1

错误:加载 conftest '/home/runner/work/gitworkflow2/gitworkflow2/backend/tests/conftest.py' 时出现导入错误。 tests/conftest.py:3:在 从主导入应用程序 main.py:11:在 Base.metadata.create_all(bind=engine)

E sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2003, “无法连接到'localhost'上的MySQL服务器([Errno 111] 连接被拒绝)”)

python sqlalchemy github-actions fastapi

评论

0赞 user2325446 11/16/2023
问题出在这行代码上:Base.metadata.create_all(bind=engine)。嘲笑效果很好。问题是,在配置中,这会在数据库中创建所有模型。因此,这应该只能手动运行。我现在修改为一个函数,它在我的管道中完美运行。

答: 暂无答案