unittest和mock

requirements.txt

nose
sqlalchemy
mysql-connector

controller.py

from lessweb.plugin.database import DbServ

import service
from model import Reply, Pager

def list_reply(serv:DbServ, reply:Reply, pager:Pager, /):
    replys = service.list_reply(serv, reply, pager)
    return {'code': 0, 'list': replys, 'page': pager}

service.py

from typing import List
from lessweb.plugin.dbplugin import DbServ
from model import Reply, Pager

def list_reply(serv:DbServ, reply:Reply, pager: Pager) -> List[Reply]:
    ...

test.py

from typing import cast
from unittest import TestCase
from unittest.mock import ANY, DEFAULT, patch
from lessweb.plugin.dbplugin import DbServ

from controller import list_reply
from model import Reply, Pager

class TestListReplyController(TestCase):
    @patch('service.list_reply')
    def test_list_reply(self, list_reply_mock):
        list_reply_mock.side_effect = (
            lambda _, a, b: (
                self.assertEqual((a.nickname, a.age), ('nn', 33)),
                self.assertEqual((b.pageNo, b.pageSize), (3, 4)),
            ) and []
        )
        pager = Pager()
        pager.pageNo, pager.pageSize = 3, 4
        reply = Reply()
        reply.nickname = 'nn'
        reply.age = 33
        # CALL controller.list_reply
        serv = cast(DbServ, '_')  # a fake serv
        ret = list_reply(serv, reply, pager)
        self.assertEqual(ret, {'code': 0, 'list': [], 'page': pager})
        list_reply_mock.assert_any_call(serv, ANY, ANY)

测试命令: nosetests test.py
测试结果:

.
----------------------------------------------------------------------
Ran 1 tests in 0.003s

OK

参考文档