如何模拟 APIView 上的属性以在 django-rest-framework 中进行单元测试

How to mock out an attribute on an APIView for unit tests in django-rest-framework

我有一个 APIView 可以点击外部 API 本身来汇总结果。我这样定义它:

class SampleView(APIView):
    api = query_api()

    def get(self, request, id):
        result = self.api.query(id)
        return HttpResponse(status=200)

我有一个模拟的 API 来使它可以测试,而无需在我的单元测试中将外部 API 作为依赖项。我想在 运行 单元测试之前做类似 SampleView.api = fake_api() 的事情。

如何换出这样的单个属性,以便用模拟的单元测试替换具体的 class?

我真的没有发现将 api 对象作为 class 属性有任何显着优势。不属于视图,

您可以在 get 请求中实例化 object。通过这样做,模拟是直截了当的。

In [21]: class ExternalApi(object):
    def __init__(self, **kwargs):
        print("APIService")
   ....:

In [22]: class MockedExternalApi(object):
    def __init__(self, **kwargs):
        print("FakeApiService")
   ....:

In [23]: def query_api():
    return ExternalApi()
   ....:

In [24]: class MyView(object):
    def get(self, request):
        api = ExternalApi(23)
        return "Something"
   ....:

In [25]: @mock.patch('__main__.ExternalApi')
def test(mocked_api):
    mocked_api.return_value = MockedExternalApi()

    view = MyView()

    assert view.get({}) == "Something"
   ....:

In [26]: test()
FakeApiService

您还可以在 query_api 和 return 中查找 settings 变量,具体取决于场景。