【问题标题】:Python OS module os.remove called is not working调用的 Python OS 模块 os.remove 不起作用
【发布时间】:2022-11-14 16:47:10
【问题描述】:

我正在尝试模拟 Python OS 模块模拟,但它不起作用

我的代码 os_mock.py:

import os 

class MyTestMock:

    def rm(self):
        # some reason file is always hardcoded
        file_path = "/tmp/file1"
        if os.path.exists(file_path):
            os.remove(file_path)
            print(file_path, 'removed successfully')
        else:
            print(file_path, 'Does not exist')

我的测试用例文件 test_os_mock.py

import os
import unittest
from unittest.mock import patch
from os_mock import MyTestMock


class TestMyTestMock(unittest.TestCase):

    @patch('os.path')
    @patch('os.remove')
    def test_rm(self, mock_remove, mock_path):
        my_test_mock = MyTestMock()
        mock_path.exists.return_vallue = False
        my_test_mock.rm()
        self.assertFalse(mock_remove.called)

        mock_path.exists.return_vallue = True
        my_test_mock.rm()
        self.assertTrue(mock_remove.called)

当我运行测试用例时,我遇到了错误

F
======================================================================
FAIL: test_rm (__main__.TestMyTestMock)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/unittest/mock.py", line 1336, in patched
    return func(*newargs, **newkeywargs)
  File "/Users/vuser/code/MP-KT/mock/test_os_mock.py", line 15, in test_rm
    self.assertFalse(mock_remove.called)
AssertionError: True is not false

----------------------------------------------------------------------
Ran 1 test in 0.008s

FAILED (failures=1)

我知道我在模拟时做错了什么,但我无法弄清楚,我有几个堆栈溢出链接,我跟着它,但没有帮助

【问题讨论】:

  • 您的代码中有错字:return_vallue 而不是 return_value

标签: python python-3.x unit-testing pytest


【解决方案1】:

我只对您的测试文件做了一些更改,而文件os_mock.py 保持不变。

return_vallue改成return_value就够了

如果您将return_vallue 更改为return_value,您的测试将成功通过,因此这些更改(在出现错误的2 个点)就足够了。

具体变化如下:

  • mock_path.exists.return_vallue=False --> mock_path.exists.return_value=False (return_value是不正确的)
  • mock_path.exists.return_vallue=True --> mock_path.exists.return_value=True (return_value是不正确的)

通过 assert_not_called() 和 assert_called_once() 改进测试

最重要的变化是return_vallue --> return_value,但在我看来unittest.mock 包提供了方法assert_not_called()assert_called_once() 可以改进您的测试。
例如self.assertTrue(mock_remove.called) 确保您调用了模拟方法,而不是mock_remove.assert_called_once() 检查您是否只调用了一次该方法。

因此,我建议进行以下更改:

  • self.assertFalse(mock_remove.called) --> mock_remove.assert_not_called()
  • self.assertTrue(mock_remove.called) --> mock_remove.assert_called_once()

新文件test_os_mock.py

显示更改后,文件test_os_mock.py变成:

import os
import unittest
from unittest.mock import patch
from os_mock import MyTestMock

class TestMyTestMock(unittest.TestCase):

    @patch('os.path')
    @patch('os.remove')
    def test_rm(self, mock_remove, mock_path):
        my_test_mock = MyTestMock()

        # return_vallue --> return_value
        mock_path.exists.return_value = False
        my_test_mock.rm()
        mock_remove.assert_not_called()
        #self.assertFalse(mock_remove.called)

        # return_vallue --> return_value
        mock_path.exists.return_value = True
        my_test_mock.rm()
        mock_remove.assert_called_once()
        #self.assertTrue(mock_remove.called)

if __name__ == "__main__":
    unittest.main()

assert_call_once_with()

在您的测试用例中,比assert_called_once() 更好的是方法assert_called_once_with(),而使用这种其他方法,您的测试将如下所示:

@patch('os.path')
@patch('os.remove')
def test_rm(self, mock_remove, mock_path):
    my_test_mock = MyTestMock()
    mock_path.exists.return_value = False
    my_test_mock.rm()
    mock_remove.assert_not_called()

    mock_path.exists.return_value = True
    my_test_mock.rm()
    # here is the NEW CHANGE
    mock_remove.assert_called_once_with("/tmp/file1") 

This link 对于理解 Python 中的 Mocking 对象非常有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-29
    相关资源
    最近更新 更多