我在類方法中有以下背景關系管理器,我想模擬單元測驗。
def load_yaml_config(self) -> dict:
"""
Load the config based on the arguments provided.
Returns: dict
dictionary which will be used for configuring the logger, handlers, etc.
"""
with open(self.yaml_path, 'r') as config_yaml:
return yaml.safe_load(config_yaml.read())
我怎么能做到呢?
編輯:
正如@chepner 建議的那樣(我不能接受他/她的回答,因為它是通過評論),最好的方法似乎是使用 unittest 的 mock_open 功能。
這樣,我可以簡單地去:
import unittest.mock as um
with um.patch('builtins.open', um.mock_open(read_data=YAML_TEST)):
h = MyClass.load_yaml_config()
uj5u.com熱心網友回復:
如果您想重構此代碼以便能夠在safe_load無需實際open檔案或補丁的情況下測驗部件builtins.open,您可以執行以下操作:
def load_yaml_config(self) -> dict:
"""
Load the config based on the arguments provided.
Returns: dict
dictionary which will be used for configuring the logger, handlers, etc.
"""
with open(self.yaml_path, 'r') as config_yaml:
return self._load_yaml_config(config_yaml.read())
def _load_yaml_config(self, yaml_text: str) -> dict:
return yaml.safe_load(yaml_text)
然后在你的測驗中:
TEST_YAML_DATA = """
stuff:
other_stuff
"""
def test_load_yaml_config():
assert WhateverMyClassIs()._load_yaml_config(TEST_YAML_DATA) == {
'stuff': 'other_stuff'
}
修改以使用實際適當的 YAML 格式和正確的預期 dict 輸出。
請注意,所有這些都是真正的測驗yaml.safe_load(應該已經有了自己的單元測驗)以及您的代碼呼叫它的事實。除了變數名稱中的拼寫錯誤(使用 linter 或靜態型別分析器更容易捕獲)之外,很難想象此測驗可能捕獲/防止什么型別的錯誤。
實際上,我可能根本不會費心在單元測驗中覆寫這個功能,而是會嘗試進行某種更大的集成測驗(使用真實檔案),其中涉及加載配置作為一些更大的測驗場景的一部分。
uj5u.com熱心網友回復:
簡單的方法
只需在您的測驗代碼中創建適當的 yaml 檔案。但你可能不想要那樣,因為你正在制作這篇文章。
一個帶有嘲諷的黑客
您可以open在模塊范圍內使用模擬覆寫:
# test_YourClass.py
builtin_open = open
class open:
def __init__(self, *args, **kwargs):
pass
def __enter__(self):
pass
def __exit__(self, exc_type, exc_value, exc_traceback):
pass
def read(self):
return 'hardcoded file contents for testing'
# Test here
open = builtin_open
這段代碼只是一個大概的思路,我沒有運行過。它可能需要一些額外的作業,例如引數化模擬檔案內容。
依賴注入
open()我想,“正確”的方法是在類中取消硬編碼呼叫并注入背景關系管理器。由你決定。我個人不喜歡僅僅為了單元測驗的目的而注入一切。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/389709.html
