Python中使用unittest模拟类

2024-04-19 10:17:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我正试着模仿一个学生单元测试.mock. 你知道吗

我的软件包和模块结构如下:

  • 服务
    • 服务_一个.py你知道吗
  • 存储库
    • 存储库_蒙哥德比你知道吗
  • 试验
    • 服务
      • 测试服务_一个.py你知道吗

类存储库_蒙哥德比在类服务中使用_一个.py(通过导入类)。你知道吗

这是文件的代码。你知道吗

文件存储库_蒙哥德比

class RepositoryMongoDB:

    def __init__(self):
        self.library = []

    def save(self, thing):
        self.library.append(thing)
        return True

文件服务_一个.py

from repository.RepositoryBookList import RepositoryBookList

class ServiceRodri:

    def __init__(self):
        self.repository = RepositoryMongoDB()

    def save_service(self, thing):
        # Do validation or something else
        return self.repository.save(thing)

现在我想模仿一下ServiceRodri类,下面是我要做的。你知道吗

import unittest
from unittest.mock import patch
from service.service_one import ServiceOne

class ServiceOneTest(unittest.TestCase):

    def setUp(self):
        self.service_one = ServiceOne()

    @patch('service.service_one.RepositoryMongoBD')
    def test_get_one_book_if_exists_decorator(self, mock_repo):
        mock_repo.save.return_value = "call mock"
        result = self.serviceRodri.save_service("")
        self.assertEquals("call mock", result)

我希望在调用类RepositoryMongoBD的方法“save”返回分配给它的结果时。但这不会发生。你知道吗

我也试过这样做。你知道吗

    @patch('repository.repository_mongodb.RepositoryMongoDB')
    def test_get_one_book_if_exists_decorator(self, mock_repo):
        mock_repo.save.return_value = "call mock"
        result = self.serviceRodri.save_service("")
        self.assertEquals("call mock", result)

但也不管用。你知道吗

但是如果我试图用这种方式模拟函数save()。你知道吗

    @patch('service.service_one.RepositoryMongoDB.save')
    def test_get_one_book_if_exists_decorator_2(self, mock_repo):
        mock_repo.return_value = "call mock"
        result = self.serviceRodri.save_service("")
        self.assertEquals("call mock", result)

工作正常!!!我知道它所做的是当调用save()在服务模块中找到时,它被mock替换。你知道吗

正确的方法是什么?(也是最好的方法)

我是Python世界里的乞丐。我已经搜索并阅读了很多文章,但是所有的例子都非常简单(比如sum()方法)。我用其他语言测试过,但从未用Python测试过。你知道吗


Tags: pyimportselfreturnrepositorysavedefservice
1条回答
网友
1楼 · 发布于 2024-04-19 10:17:25

如果你坚持使用patch,你最后的尝试是正确的。你知道吗

以前的尝试不起作用的原因是,在导入之后应用了修补程序,因此您没有修补您认为是的对象。你知道吗

我已经用了很长一段时间的补丁,这仍然咬我偶尔。所以我建议使用简单的基于构造函数的依赖注入。你知道吗

使用中的

class ServiceOne:

    def __init__(self, respository):
        self.repository

service_rodri = ServiceRodri(RepositoryMongoDB())初始化它,可能在__init__文件或其他文件中。然后在测试中,可以在设置中创建此模拟。你知道吗

class ServiceOneTest(unittest.TestCase):

    def setUp(self):
        self.repository = MagicMock()
        self.service_one = ServiceOne(self.repository)

N.B.修补与依赖注入:

补丁还将把测试耦合到程序的导入结构中。这使得严格改变模块结构的安全重构更加困难。当您在进行更改之前需要进行一些测试时,最好与遗留代码一起使用。你知道吗

相关问题 更多 >