用python模拟DNS解析器答案

时间:2018-08-06 11:17:24

标签: python unit-testing dns mocking

我有一个构建查询的方法,将其传递给负责解决该查询的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的列表。有简单的方法吗?

1 个答案:

答案 0 :(得分:2)

您可以模拟__make_query()方法(有点困难,因为您现在需要手动更改名称以匹配类私有名称空间保护,请参见What is the meaning of a single- and a double-underscore before an object name?),或模拟{{ 1}}对象。

您不必完全匹配此处生成的实例,只需生成足够的属性即可通过集合。对于Resolver()项目中的SRV类,您需要的是一个具有dnspythonportprioritytarget属性的对象,并带有weight的行为类似于target实例。后者稍微复杂一点,但是您只需要存根您的代码需求

您可以使用unittest.mock library轻松完成此操作,无论是否精确指定对象。对于您的代码,您只使用3个属性,因此您的模拟只需要返回一个列表就可以了。

您可以使用create_autospec() function来生成一个模拟对象,该对象仅限于原始类支持的属性。这可以帮助检测代码中使用原始类永远不允许的属性或方法的错误。如果您不使用规范,则默认为生成允许 all 属性的模拟对象,并假装那些属性存在(并且每次这样的访问都会产生更多的模拟对象)。

因此,如果您需要dns.name.Name实例,那么我将使用:

SRV