3 回答

TA貢獻(xiàn)1868條經(jīng)驗 獲得超4個贊
您需要修補正在測試的模塊中的符號“A”,即“B”。
當(dāng)你這樣做時@mock.patch("full.path.A")
,它應(yīng)該是:
@mock.patch("full.path.to.B.A")
現(xiàn)在A
模塊中的符號B
用你的模擬打了補丁。

TA貢獻(xiàn)1998條經(jīng)驗 獲得超6個贊
你不是錯過了文件本身的名稱嗎?
@mock.patch( 'namespacename.mylibname.stats_collector.mylibname_stats_collector.StatsCollector')

TA貢獻(xiàn)1852條經(jīng)驗 獲得超1個贊
當(dāng)我寫這篇文章時,你可能已經(jīng)想通了。
經(jīng)驗法則:不要在定義類或函數(shù)的地方打補丁,而是在使用它們的地方打補丁。
a.py
class A:
def exponent(self, a, b)
return a ** b
b.py
from a import A
class B:
def add_constat(a, b, c)
return A().exponent(a, b) + c
為了測試 add_constant 方法,您可能會想像這樣修補 A
TestB:
@patch('a.A.exponent', mock_a)
test_add_constant(self, mock_a)
這是錯誤的,因為您正在修補給出定義的文件中的類。
A 在類 B 的文件 b 中使用。因此,您應(yīng)該修補該類。
TestB:
@patch('b.A')
test_add_constant(self, mock_a):
# mock_a is fake class of A, the return_value of mock_a gives us an instance (object) of the class(A)
instance_a = mock_a.return_value #
# we now have instance of the class i.e A, hence it is possible to call the methods of class A
instance_a.exponent.return_value = 16
assert 26 = B().add_constant(2,4,10)
我對您的代碼進(jìn)行了一些修改,以便它可以在我的 Python 環(huán)境中使用。
stats_collector.py
class StatsCollector:
def __init__(self, user_id, app_id):
self.user_id = user_id
self.app_id = app_id
def stat(self):
return self.user_id + ':' + self.app_id
mydb.py
from stats_collector import StatsCollector
import logging
class Db:
# constructor
def __init__(self, db_name):
self.db_name = db_name
def begin_transaction(self, user_id, app_id):
logging.info("Begin")
stat = StatsCollector(user_id, app_id).stat()
if stat:
return user_id + ':' + app_id
return "wrong User"
使用類似的比喻:為了測試文件 mydb.py 的 Db 類中的“begin_transaction”,您需要修補 mydb.py 文件中使用的 StatsCollector 類
test_mydb.py
from unittest.mock import patch
from unittest import TestCase
class TestDb(TestCase):
@patch('mydb.StatsCollector')
def test_begin_transaction(self, db_class_mock):
# db_class_mock is the mock of the class, it is not an instance of the DB class.
# to create an instance of the class, you need to call return_value
db_instance = db_class_mock.return_value
db_instance.stat.return_value = 1
# i prefere to do the above two lines in just one line as
#db_class_mock.return_value.stat.return_value = 1
db = Db('stat')
expected = db.begin_transaction('Addis', 'Abeba')
assert expected == 'Addis' + ':' + 'Abeba'
# set the return value of stat method
db_class_mock.return_value.stat.return_value = 0
expected = db.begin_transaction('Addis', 'Abeba')
assert expected == "wrong User"
我希望這可以幫助網(wǎng)絡(luò)中的某人
添加回答
舉報