我的大部分單元測驗經驗都是使用 Java,現在我轉向 Python。我需要測驗一個方法(來自物件 B)是否在另一個方法(在物件 A 中)中被呼叫。
在 Java 中,測驗方法必須將 B 的模擬或間諜版本傳遞給 A 的建構式,以便在呼叫 B 方法時使用。我需要在 Python 中做同樣的事情嗎?或者有沒有更簡單的方法?(我提出了后者的可能性,因為據我所知,Python 在不同組件之間強制隔離方面似乎相對寬松。)
以下是我如何以“Java 方式”執行此操作。有兩個 Python 檔案在測驗中(用于物件 A 和 B)和一個測驗程式。請注意,必須修改物件 A 的建構式以適應測驗。
obj_a.py
from obj_b import *
class ObjA:
def __init__(self, *args):
if len(args) > 0:
self.objb = args[0] # for testing
return
self.objb = ObjB()
def methodCallsB(self, x, y):
return self.objb.add(x, y)
obj_b.py
class ObjB:
def add(self, x, y):
return x y
測驗.py
import unittest
from unittest.mock import patch, Mock
from obj_a import *
from obj_b import *
class TTest(unittest.TestCase):
@patch("obj_b.ObjB")
def test_shouldCallBThroughA(self, mockB):
# configure mock
mockB.add = Mock(return_value=137)
obja = ObjA(mockB)
# invoke test method
res = obja.methodCallsB(4, 7)
print("result: " str(res))
# assess results
self.assertEqual(137, res)
mockB.add.assert_called_once()
args = mockB.add.call_args[0] # Python 3.7
print("args: " str(args))
self.assertEqual((4, 7), args)
if __name__ =='__main__':
unittest.main()
同樣,有沒有更簡單的方法來測驗 ObjB::add 是從 ObjA 呼叫的嗎?
uj5u.com熱心網友回復:
除了@Alex 在評論中提到的設計可能存在的問題外,使用模擬還存在一些錯誤。
首先,你在嘲笑錯誤的物件。正如object_a您所做的那樣from obj_b import *(順便說一句,這是一種不好的風格 - 只匯入您需要的物件),您需要修補匯入到的物件參考obj_b,例如obj_a.ObjB(查看修補位置)。
其次,您必須模擬實體而不是類上的方法呼叫,例如模擬mockB.return_value.add而不是mockB.add.
您的測驗實際上只起作用,因為您沒有測驗您的真實功能,只是您的模擬。如果您正確地進行了修補,則無需在__init__.
所以,放在一起,這樣的事情應該可以作業:
obj_a.py
class ObjA:
def __init__(self):
self.objb = ObjB()
...
測驗.py
class TTest(unittest.TestCase):
@patch("obj_a.ObjB")
def test_shouldCallBThroughA(self, mockB):
# for convenience, store the mocked method
mocked_add = mockB.return_value.add
mocked_add.return_value = 137
obja = ObjA()
res = obja.methodCallsB(4, 7)
self.assertEqual(137, res)
mocked_add.assert_called_once()
args = mocked_add.call_args[0]
self.assertEqual((4, 7), args)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/530687.html
標籤:Python单元测试嘲弄python-unittest间谍
