【发布时间】:2020-05-12 17:11:53
【问题描述】:
当我直接使用 unittest.mock.patch 修补方法时,我可以使用 mock.assert_call_with() 函数来正确断言该方法是否使用某些值调用。但是,当我直接修补类时,即使调用了类和方法,我在类本身或任何类方法上使用的任何断言都会返回“AssertionError:未调用”。
unittest 文档中有成功修补类和使用断言的示例:unittest mock doc
这是我对 SiteMetaData 类方法直接修补和 EdgeAPIRoutes 类修补的测试:
测试
@patch("repo.routes.EdgeAPIRoutes")
@patch("repo.site_meta_data.SiteMetaData.get_repo_type")
@patch("repo.site_meta_data.SiteMetaData.get_edge_api_inputs")
def test_get_route_list_repo_interface_edge(self, mock_edge_api_inputs,
mock_get_repo_type, mock_edge_api_routes_class):
"""
Test that SiteMetaData.get_route_list is used
appropriately and returns expected values from
mock as a valid response object
"""
from usecase import interface
from usecase import request_objects
from usecase.response_objects import ResponseSuccess
from utils.utils import DatetimeString
all_filters = {"filters" : {"parent_company" : "parent_1",
"site" : "site_1",
"start_date" : DatetimeString("2020-01-01 00:00:00.000"),
"end_date" : DatetimeString("2020-05-01 00:00:00.000")
}
}
example_route_list = [
"route_1",
"route_2",
"route_3"
]
edge_inputs = {
"edge_site" : "edge_site_name",
"edge_key" : "ffff-ffff-ffff"
}
error_response = None
mock_edge_api_inputs.return_value = [
edge_inputs["edge_site"],
edge_inputs["edge_key"],
error_response
]
mock_get_repo_type.return_value = [
"Minestar Edge",
error_response
]
mock_edge_api_routes_class.get_route_list.return_value = [
example_route_list,
error_response
]
resp = interface.get_route_list(request=request_objects.RouteList.request_wfilters(all_filters))
mock_get_repo_type.assert_called_with(all_filters["filters"]["parent_company"],
all_filters["filters"]["site"])
mock_edge_api_inputs.assert_called_with(all_filters["filters"]["parent_company"],
all_filters["filters"]["site"])
mock_edge_api_routes_class.get_route_list.assert_called_with(all_filters["filters"]["start_date"],
all_filters["filters"]["end_date"])
mock_edge_api_routes_class.assert_called_once_with(edge_inputs["edge_site"], edge_inputs["edge_key"])
self.assertTrue(bool(resp))
self.assertEqual(resp.type_, ResponseSuccess.SUCCESS)
self.assertEqual(resp.value["routes"], example_route_list)
方法
def get_route_list(request):
"""
"""
interfacelog.info("running get_route_list")
if bool(request):
repo_type, repo_type_error = site_meta_data.get_repo_type(request.filters["parent_company"],
request.filters["site"])
if repo_type_error is not None:
'''
handle any get repo type system errors
'''
pass
if repo_type == "Minestar Edge":
edge_site, edge_key, edge_error = site_meta_data.get_edge_api_inputs(request.filters["parent_company"],
request.filters["site"])
ear = EdgeAPIRoutes(edge_site, edge_key)
rl, routes_error = ear.get_route_list(request.filters["start_date"],
request.filters["end_date"])
if routes_error is not None:
'''
handle any get routes system error
'''
pass
success_resp = response_objects.ResponseSuccess()
success_resp.value = {"routes" : rl}
return success_resp
else:
'''
handle and errors due to an invalid request
'''
return response_objects.ResponseFailure.build_from_invalid_request_object(request)
结果
SiteMetaData 修补方法的断言通过,而 EdgeAPIRoutes 类和方法的断言失败。根据文档,似乎两种修补方法都应该通过它们的断言。
【问题讨论】:
-
这取决于你如何导入类。
get_route_list是在哪个模块中实现的?我猜我会说你做了from repo.routes import EdgeAPIRoutes,你必须修补path_to_tested_module.EdgeAPIRoutes(见where to patch)。 -
谢谢。就是这样。我也错过了文档中的这个关键信息:“要在修补类的实例方法上配置返回值,您必须在(修补类的)return_value 上执行此操作”patch class method
标签: python python-3.x python-unittest