执行Django单元测试时如何禁用第三方API? [英] How can I disable a third party API when executing Django unit tests?

查看:85
本文介绍了执行Django单元测试时如何禁用第三方API?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试针对Django中针对第三方API运行操作的一些代码构建一些单元测试。具体来说,我将一些用户数据与MailChimp进行同步,并使用实现MailChimp API的库。

I'm trying to build some unit tests against some code I have in Django that runs operations against a third party API. Specifically, I'm synchronizing some user data with MailChimp and using a library that implements the MailChimp API.

我有一个自定义类 MailChimpAPI 这实际上充当我正在使用的Python库周围的薄包装。以下是代码的一些相关部分:

I have a custom class MailChimpAPI that essentially acts as a thin wrapper around the Python library I'm using. Here are some relevant portions of the code:

class MailChimpAPI(object):
    """
    A wrapper for implementing business logic and exception handling around
    the PyChimp API
    """
    ...

    def __init__(self, api_key, primary_list_id, merge_keys, use_secure=True, timeout=None):
        ...

        # setup api
        self.api_key = api_key
        self.api = PyChimp(self.api_key)

        ...

    ...


    def _call(self, method_name, args=[], kwargs={}):
        """Calls the PyChimp API directly"""
        result = getattr(self.api, method_name)(*args, **kwargs)
        if self.api.errorCode:
            self._raise_mailchimp_exception()
        else:
            return result

    ...

我删除了(...)大多数实现业务逻辑的代码,但是显着的这里是我将 api 属性设置为 __ init __()中的PyChimp(第三方库) ,并且所有对该库的实际调用都是在 _call()函数中进行的。

I snipped out (...) most of the code that implements the business logic etc., but the salient aspect here is that I set the api attribute to an instance of PyChimp (the third party library) in __init__(), and all of the actual calls to that library are made in the _call() function.

我是有些新的单元测试,所以我很难找出最好的方法来处理这个。我有一个想法是将PyChimp库实例化到我的类之外,并将其传递给构造函数。另一个想法是在测试这个我可以嘲笑 _call 方法,以便它不会击中实际的库。

I'm somewhat new to unit testing, so I'm having a hard time figuring out the best way to approach this. One idea I had was to instantiate the PyChimp library outside of my class and pass it into the constructor. Another idea is in testing this I could mock the _call method so that it doesn't hit the actual library.

我的第一个问题是,显然,我不想对实际的API执行任何测试代码。所以我试图找出最好的方式来存根或模拟那个API,以便在测试期间对它进行的调用实际上不会执行。理想情况下,我希望将该模拟API作为Django测试套件中的所有测试运行。例如,我正在探索通过 post_save 信号创建用户帐户时将用户同步到MailChimp的可能性。因此,我显然不希望在Django身份验证应用程序中运行的测试也可以触发实际的API。

The number one issue I have is that, obviously, I don't want to execute any testing code against the actual API. So I'm trying to figure out the best way to "stub" or "mock" that API so that calls made to it during testing don't actually execute. Ideally, I'd like to have that mock API present as all tests in the Django test suite run. For example, I'm exploring the possibility of syncing a user to MailChimp whenever a User account is created via the post_save signal. For that reason, I obviously don't want the tests that run in the Django Authentication app to trigger the actual API either.

我希望Django有一些全局设置/有没有任何人有任何建议,如何干净地替代一个活的API,可以与...一起工作,但是似乎没有任何东西。

I was hoping Django had some global setup / teardown hooks or signals I could work with, but there doesn't seem to be anything.

在测试期间假装一个?或者我完全错了吗?

Does anyone have any suggestions for how to cleanly substitute a "live" API with a pretend one during testing? Or am I doing it totally wrong?

我很有信心我可以闯入解决方案,但如果有人能够分享,一些关于最好的方法来处理这种事情的智慧。

I am quite confident I can hack my way to a solution, but it would be great if someone would be kind of enough to share some wisdom about the "best" way to approach this kind of thing.

推荐答案

你建议,在外面创建api对象并将其传递给构造函数。这将允许您轻松替换api类进行测试。

The best way to go about it is probably as you suggest, creating the api object outside and passing it to the constructor. This will allow you to replace the api class easily for testing.

您可以创建一个MockPyChimp类,它具有与实际PyChimp API相同的方法。这样,您可以轻松地在整个测试中重复使用相同的模拟类。

You could create a MockPyChimp class, which has the same methods as the actual PyChimp api. This way you could easily reuse the same mock class across your tests.

我不够熟悉python / django单元测试,以便能够建议任何特定的库帮助这个,但我会假设存在某种嘲笑的图书馆等。

I'm not familiar enough with python/django unit testing to be able to suggest any specific libraries to assist in this, but I would assume there exists some sort of mocking libraries or such.

这篇关于执行Django单元测试时如何禁用第三方API?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆