单元测试-mock-登录
auth.py
import mydb def login_check(username:str,password:str): # 去数据库查询用户;调用 db 模块的`find_user_by_name`函数,把用户名传进去,去查找这个用户 user = mydb.find_user_by_name(username) if not user: return {"code":400,"msg":"用户不存在"} if user["pwd"] == password: return {"code":200,"msg":"登录成功"} else: return {"code":400,"msg":"密码错误"}
mydb.py
# db.py 数据库文件(我们单元测试不会真正执行这里!会mock掉)
def find_user_by_name(username):
# 真实项目这里会连接MySQL查数据
return None
test_auth.py
# 从unittest.mock包导入patch工具(单元测试用来模拟/伪造函数)
from unittest.mock import patch
# 从auth模块,导入要测试的登录函数 login_check
from auth import login_check
import unittest
# 必须新建类,继承 unittest.TestCase
class TestLogin(unittest.TestCase):
# @patch:补丁装饰器。含义:把 auth.py 里面的 find_user_by_name 函数,替换成一个假的mock函数(模拟数据库查询,不用真连数据库)
@patch("auth.mydb.find_user_by_name")
#测试用例:登录成功场景;mock_find_user就是替换后的假函数对象
def test_login_success(self,mock_find_user):
# ========= 1 设置mock伪造返回数据 =========
# 伪造【数据库查询】返回:查到用户,用户名lily,密码123456
mock_find_user.return_value = {"username":"lily","pwd":"123456"}
# ========= 2 调用登录函数 =========
# 执行登录,传入用户名lily、密码123456
res = login_check(username="lily",password="123456")
# =========3 断言:看结果是否符合预期 =========
# 断言返回的code等于200(200代表成功)
assert res["code"] == 200
# 断言返回信息是“登录成功”
assert res["msg"] == "登录成功"
# 额外校验:确认find_user_by_name这个查询函数,**确实被调用了一次,并且参数是lily**
mock_find_user.assert_called_once_with("lily")
# 打补丁:替换auth里的find_user_by_name
@patch("auth.mydb.find_user_by_name")
# 测试用例:用户不存在场景
def test_login_user_not_exits(self,mock_find_user):
# mock返回None,代表数据库里查不到这个用户
mock_find_user.return_value = None
# 调用登录:用户名tom,密码666666
res = login_check("tom","666666")
assert res["code"] == 400
assert res["msg"] == "用户不存在"
# 打补丁,伪造查询用户的函数
@patch("auth.mydb.find_user_by_name")
# 测试用例:密码错误场景
def test_login_pwd_wrong(self,mock_find_user):
# mock查到用户lily,数据库存的密码是123456
mock_find_user.return_value = {"username":"lily", "pwd":"123456"}
# 调用登录,密码传错:wrongpass
res = login_check("lily", "wrongpass")
# 断言返回码400
assert res["code"] == 400
# 断言提示文字:密码错误
assert res["msg"] == "密码错误"
# 加这一段,直接python test_auth.py也能跑
if __name__ == '__main__':
unittest.main()
mock测试,一般是测试后台逻辑的
浙公网安备 33010602011771号