在测试一段我无法理解的Python代码时遇到了一个问题。在下面的代码中,我测试了模块的方法,该方法在找到提交时应返回200,在找不到提交时应返回404。即得到一个提交的方法是外部到我测试所以它必须在测试被模拟出模块。
运行以下代码时,第二个测试失败,因为返回的状态代码为200。当我打印analysis_result
时,它会打印出第一个测试中提供的get_single_submission
的模拟值。如果我注释掉第一个测试,则测试套件可以通过。我将不胜感激人们可能提出的任何想法或建议!
测试代码:
class AnalysisTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
pass
@classmethod
def tearDownClass(cls):
pass
def setUp(self):
pass
def tearDown(self):
pass
@mock.patch('lib.retention.Submissions')
@mock.patch('lib.retention.Analysis')
def test_analysis_get_submission(self, mock_Analysis, mock_Submissions):
mock_Submissions.return_value.get_single_submission.return_value = Submission(
md5="md5",
analyze_completed="01-23-12"
)
from api import analysis
test_event = {
"pathParameters": {
"query": ["test"],
"id": 1
}
}
analysis_result = analysis.analysis_get(test_event)
print(analysis_result)
self.assertEqual(analysis_result["statusCode"], 200)
@mock.patch('lib.retention.Submissions')
@mock.patch('lib.retention.Analysis')
def test_analysis_get_submission_not_found(self, mock_Analysis, mock_Submissions):
mock_Submissions.return_value.get_single_submission.return_value = None
from api import analysis
test_event = {
"pathParameters": {
"query": ["test"],
"id": 1
}
}
analysis_result = analysis.analysis_get(test_event)
print("not found")
print(analysis_result)
self.assertEqual(analysis_result["statusCode"], 404)
和pytest结果:
@mock.patch('lib.retention.Submissions')
@mock.patch('lib.retention.Analysis')
def test_analysis_get_submission_not_found(self, mock_Analysis, mock_Submissions):
mock_Submissions.return_value.get_single_submission.return_value = None
from api import analysis
test_event = {
"pathParameters": {
"query": ["test"],
"id": 1
}
}
analysis_result = analysis.analysis_get(test_event)
print("not found")
print(analysis_result)
self.assertEqual(analysis_result["statusCode"], 404)
电子的AssertionError:200 = 404
api/tests/analysis_test.py:72: AssertionError
------------------------------------------------------------------------------- Captured stdout call --------------------------------------------------------------------------------
not found
{'statusCode': 200, 'isBase64Encoded': False, 'headers': {'Content-Type': 'application/json'}, 'body': '{\n "metadata": {\n "md5": "md5",\n "analyzed_date": "01-23-12"\n }\n}'}
更新: 文件结构
project/lib/retention.py
/api/analysis.py
/tests/analysis_test.py
更新2:
我打印出来Submissions
在analysis_get
,并发现了同样的模拟正由两种测试某种方式
<MagicMock name='Submissions' id='4599620440'>
答案 0 :(得分:1)
以上代码中的问题是,我假设每个测试都可以通过在每个测试中声明analysis
来导入其自己的from api import analysis
模块的新版本。实际上,这仅是第一次导入analysis
,而不会随后导入。由于是单次导入,因为Submissions
是analysis
模块中的有状态组件,所以仅将第一个模拟_Submissions修补到该类中。解决方案是编辑代码以使用reload
包在每个测试中重新加载导入。
from importlib import reload
class AnalysisTest(unittest.TestCase):
@classmethod
@mock.patch('lib.retention.Submissions')
@mock.patch('lib.retention.Analysis')
def setUpClass(cls):
from api import analysis
@classmethod
def tearDownClass(cls):
pass
def setUp(self):
pass
def tearDown(self):
pass
@mock.patch('lib.retention.Submissions')
@mock.patch('lib.retention.Analysis')
def test_analysis_get_submission(self, mock_Analysis, mock_Submissions):
mock_Submissions.return_value.get_single_submission.return_value = Submission(
md5="md5",
analyze_completed="01-23-12"
)
from api import analysis
reload(analysis)
test_event = {
"pathParameters": {
"query": ["test"],
"id": 1
}
}
analysis_result = analysis.analysis_get(test_event)
print(analysis_result)
self.assertEqual(analysis_result["statusCode"], 200)
@mock.patch('lib.retention.Submissions')
@mock.patch('lib.retention.Analysis')
def test_analysis_get_submission_not_found(self, mock_Analysis, mock_Submissions):
mock_Submissions.return_value.get_single_submission.return_value = None
from api import analysis
reload(analysis)
test_event = {
"pathParameters": {
"query": ["test"],
"id": 1
}
}
analysis_result = analysis.analysis_get(test_event)
print("not found")
print(analysis_result)
self.assertEqual(analysis_result["statusCode"], 404)