如何测试返回某些结果并具有副作用的函数?

时间:2018-12-28 12:30:47

标签: python django unit-testing testing

我有一个函数,该函数返回某些内容,但同时具有副作用。我应该只测试该函数返回的值,还是也需要测试副作用的结果?

@slack_interactions.on('admin_add')
def handle_admin_add(payload):
    team_id = payload['team']['id']
    user_id = payload['user']['id']
    action_value = payload['actions'][0]['selected_options'][0]['value']

    user = SlackUser.objects.find_by_ids(team_id, action_value)

    if user and not user.is_bot:
        user.make_admin()

    return build_admins_message(team_id, user_id)

2 个答案:

答案 0 :(得分:4)

简短回答,请同时测试。

长答案: 您应该永远记住,测试是验证给定输入是否期望特定输出

请记住,如果您的功能修改了状态(副作用),则需要验证状态是否按预期进行了修改。如果它还返回了一个值,那么您需要验证返回的值是否符合预期值。

测试是确保您的代码健壮的一种好方法,只要您了解其背后的禅宗即可。 我必须测试我的期望,并设计出意外的东西。

但是,单独测试不能产生良好的代码,如果您拥有的方法可以完成两项以上的工作,则可能设计不正确。通常,影响状态的方法不应返回值,反之亦然。它不是一成不变的,但是如果遵循该约定,则更容易将系统分离。

有些编码原则可以防止将来出现麻烦,其中之一就是“单一责任原则”。在这种情况下,您的功能显然违反了。我建议您看看SOLID编程原则,这是值得的,相信我。一旦采用它们,单元测试就会自然而然地完成。

答案 1 :(得分:1)

我建议同时进行测试,因为副作用和返回值都是函数行为的一部分,也是与代码进行交互的接口的一部分。

要实现此目的,您可以使用内置unittest.mock之类的模拟库,这样就可以模拟对user.make_admin()和完整SlackUser对象的调用。

我建议阅读MagicMockpatch的文档以简化测试。

测试愉快!