Mockh模組不起作用問題

2021-10-24 16:25:59 字數 2441 閱讀 1941

最近的單元測試中,使用mock模組時發現乙個乙個奇怪的問題,當使用from module import func後,如果使用mock去模擬對應的方法時,執行的依舊是原始方法,而不是模擬的方法。下面使用**解釋一下:

在專案中存在三個python檔案,其中乙個是action.py檔案,**為:

def func():

return 'original func'

第二個是execute_to_action.py檔案,其**檔案為:

from action import func

def my_func():

return func()

另乙個是test.py檔案,其**檔案為:

import unittest

from mock import patch

from execute_to_action import my_func

class mytestcase(unittest.testcase):

@patch('action.func')

def test_func(self, mock_func):

mock_func.return_value = 'new value'

result = my_func()

print(result)

if __name__ == '__main__':

unittest.main()

使用pytest執行上面的測試**,最終執行的結果是original func,說明mock沒有成功

但是採用另一種引入方式,將action.py修改為如下所示:

import action

def my_func():

return action.func()

執行結果是new value,說明這種方式是可以正常mock成功的。

按照之前使用的情況來看,import modulefrom module import func是類似,但是從mock的情況來看,這兩種使用方式存在一些細微的區別,那麼區別到底是什麼呢?

一般搜尋之後,這兩種方式執行的操作是不同的。

所以這兩種引入造成的區別是命名空間的不同,因此import的不同結果可能就是命名空間造成的。可以做出如下的解釋:

採用import module引入時,會根據原始action模組建立命名空間,呼叫my_func()方法時,是在原始的命名空間下執行的,而mock中的patch()方法使用的就是原始action模組對應命名空間,因此這種方式是可以正常模擬的。

採用from module import func的方式引入時,會將原始方法載入到當前test模組的命名空間中,而mock中的patch()方法中使用的還是原始action模組對應的命名空間,因此這種方式不能正確模擬方法。

那麼如何驗證這種猜測呢,既然from module import func是將原始方法載入到當前test模組的命名空間中,可以在mock的patch()方法中模擬的當前test模組的my_func()方法,應該就可以正常工作了。那麼將execute_to_action.py恢復原始狀態,test.py的**修改為如下所示:

import unittest

from mock import patch

from execute_to_action import my_func

class mytestcase(unittest.testcase):

@patch('execute_to_action.func')

def test_func(self, mock_func):

mock_func.return_value = 'new value'

result = my_func()

print(result)

if __name__ == '__main__':

unittest.main()

測試結果是new value,說明猜測正確

這個問題還是對python的引入機制了解不夠深入造成的。下面詳細介紹一下:

參考:

jquery ajax return不起作用

最近做專案時,發現乙個問題,但卻不知道怎麼改,耐著性子問了一下午的度娘,終於找到答案 問題 jquery ajax提交,return值一直都無法獲取 原因 ajax請求和後面的處理是非同步執行的,也就是說,有可能ajax還沒執行完,還沒走到return的部分,ajax請求後面的 已經執行完畢 所以a...

setMargins不起作用

在用viewpage做廣告滾動的效果,根據 的數量,每個 生成乙個圓點用來表示,當前 滾動的位置,但是用layoutparams 物件設定圓點的高和寬都正常,用setmargins設定圓點的間距卻無效,請高手解答 private void initui context context else ml...

gitignore不起作用

gitignore中已經標明忽略的檔案目錄下的檔案,git push的時候還會出現在push的目錄中,原因是因為在git忽略目錄中,新建的檔案在git中會有快取,如果某些檔案已經被納入了版本管理中,就算是在.gitignore中已經宣告了忽略路徑也是不起作用的,這時候我們就應該先把本地快取刪除,然後...