Python 中 Mocked Class 的 AttributeError
AttributeError on Mocked Class in Python
我正在使用 mockito 对 Python 中的程序进行单元测试。我有一个 class 像:
import boto3
import datetime
class Cache:
def __init__(self):
client = boto3.resource('s3')
self.bucket_name = 'name'
self.bucket = client.Bucket(self.bucket_name)
def setup_cache(self, cache_file='cache.csv', cache_filepath='cache'):
cache_object = self.bucket.Object(cache_file)
if cache_object.last_modified < datetime.datetime.now():
self.bucket.download_file(cache_filepath, cache_file)
else:
print('Cache already up to date')
def main():
cache = Cache()
cache.setup_cache()
我遇到的测试代码是这样的:
from mockito import mock, when
import datetime
import boto3
import mock_cache
class TestMockCache:
def test_last_mod(self):
mock_client = mock()
when(boto3).resource('s3').thenReturn(mock_client)
mock_bucket = mock()
when(mock_client).Bucket('name').thenReturn(mock_bucket)
mock_bucket.last_modified = datetime.datetime.now()
mock_cache.main()
当运行 pytest 进行单元测试时,我会抛出这个属性错误:
AttributeError: 'NoneType' object has no attribute 'last_modified'
从文档看来我可以像这样分配 'cache_mock.last_modified'。不过,我也试过了:
when(cache_mock).last_modified.thenReturn(test_date)
并得到:
AttributeError: 'StubbedInvocation' object has no attribute 'thenReturn'
我不完全理解,但假设这意味着 mockito mock() 对象不能有多个 return 值?
如有任何帮助,我们将不胜感激。我觉得我误解了一些关于 mockito 的模拟如何工作或一般模拟的基本知识。
Mock
中的 patch
可用于模拟 boto3
中的 client
。不需要return客户端的任何东西,因为它在整体上被嘲笑了。
例如:
from folder.file import your_func
from unittest.mock import patch
class TestSomething(unittest.TestCase):
@patch("botocore.client.BaseClient._make_api_call")
def test_something(self, _mock_client_boto3):
your_func()
.. do something
如果您想从客户端 return 获取某些内容,可以通过在补丁中指定 return_value
来实现,如下所示:
from folder.file import your_func
from unittest.mock import patch
class TestSomething(unittest.TestCase):
@patch("botocore.client.BaseClient._make_api_call", return_value=None)
def test_something(self, _mock_client_boto3):
your_func()
.. do something
我正在使用 mockito 对 Python 中的程序进行单元测试。我有一个 class 像:
import boto3
import datetime
class Cache:
def __init__(self):
client = boto3.resource('s3')
self.bucket_name = 'name'
self.bucket = client.Bucket(self.bucket_name)
def setup_cache(self, cache_file='cache.csv', cache_filepath='cache'):
cache_object = self.bucket.Object(cache_file)
if cache_object.last_modified < datetime.datetime.now():
self.bucket.download_file(cache_filepath, cache_file)
else:
print('Cache already up to date')
def main():
cache = Cache()
cache.setup_cache()
我遇到的测试代码是这样的:
from mockito import mock, when
import datetime
import boto3
import mock_cache
class TestMockCache:
def test_last_mod(self):
mock_client = mock()
when(boto3).resource('s3').thenReturn(mock_client)
mock_bucket = mock()
when(mock_client).Bucket('name').thenReturn(mock_bucket)
mock_bucket.last_modified = datetime.datetime.now()
mock_cache.main()
当运行 pytest 进行单元测试时,我会抛出这个属性错误:
AttributeError: 'NoneType' object has no attribute 'last_modified'
从文档看来我可以像这样分配 'cache_mock.last_modified'。不过,我也试过了:
when(cache_mock).last_modified.thenReturn(test_date)
并得到:
AttributeError: 'StubbedInvocation' object has no attribute 'thenReturn'
我不完全理解,但假设这意味着 mockito mock() 对象不能有多个 return 值?
如有任何帮助,我们将不胜感激。我觉得我误解了一些关于 mockito 的模拟如何工作或一般模拟的基本知识。
Mock
中的 patch
可用于模拟 boto3
中的 client
。不需要return客户端的任何东西,因为它在整体上被嘲笑了。
例如:
from folder.file import your_func
from unittest.mock import patch
class TestSomething(unittest.TestCase):
@patch("botocore.client.BaseClient._make_api_call")
def test_something(self, _mock_client_boto3):
your_func()
.. do something
如果您想从客户端 return 获取某些内容,可以通过在补丁中指定 return_value
来实现,如下所示:
from folder.file import your_func
from unittest.mock import patch
class TestSomething(unittest.TestCase):
@patch("botocore.client.BaseClient._make_api_call", return_value=None)
def test_something(self, _mock_client_boto3):
your_func()
.. do something