我有一个构建查询的方法,将其传递给负责解决该查询的public class PagesController : Controller
{
public IActionResult Recover(string username)
{
return View();
}
}
方法(使用dns解析器)并返回答案。然后,父方法从答案中做一些事情。我想对父方法进行单元测试;为此,我认为最好的方法是模拟_make_query
方法以返回不同的结果并测试父方法如何对此做出反应。
但是我很难模拟该方法以返回由dns解析器返回的同一对象。
这是_make_query
方法:
_make_query
调用方法的代码:
def _make_query(self, query):
query_resolver = resolver.Resolver()
return query_resolver.query(query, 'SRV')
(也作为私有方法的主要方法def _get_all_databases(self, database_parameters):
query = self._format_dns_query(database_parameters)
answers = self._make_query(query)
databases = []
for answer in answers:
databases.append(
Database(
answer.target, answer.port, answer.weight,
database_parameters.db_name
))
return databases
然后必须从返回的列表中选择一个数据库)
我有一个模拟程序可以在单元测试中从该方法返回想要的内容,但是我不知道如何重现get_database
方法所返回的对象。它应该返回一个resolver.query()
,似乎包含dns.resolver.Answer
的列表。有简单的方法吗?
答案 0 :(得分:2)
您可以模拟__make_query()
方法(有点困难,因为您现在需要手动更改名称以匹配类私有名称空间保护,请参见What is the meaning of a single- and a double-underscore before an object name?),或模拟{{ 1}}对象。
您不必完全匹配此处生成的实例,只需生成足够的属性即可通过集合。对于Resolver()
项目中的SRV
类,您需要的是一个具有dnspython
,port
,priority
和target
属性的对象,并带有weight
的行为类似于target
实例。后者稍微复杂一点,但是您只需要存根您的代码需求。
您可以使用unittest.mock
library轻松完成此操作,无论是否精确指定对象。对于您的代码,您只使用3个属性,因此您的模拟只需要返回一个列表就可以了。
您可以使用create_autospec()
function来生成一个模拟对象,该对象仅限于原始类支持的属性。这可以帮助检测代码中使用原始类永远不允许的属性或方法的错误。如果您不使用规范,则默认为生成允许 all 属性的模拟对象,并假装那些属性存在(并且每次这样的访问都会产生更多的模拟对象)。
因此,如果您需要dns.name.Name
实例,那么我将使用:
SRV