简体   繁体   English

Python-扩展API客户端类或传递实例

[英]Python - Extend an API client class or pass instance

I'm interacting with an API for which I have a Python library. 我正在与拥有Python库的API进行交互。 The library provides an APIClient class which provides all the functionality of the API. 该库提供了APIClient类,该类提供了API的所有功能。 I want to interact with this API according to some logic, and I would like to be able to test the logic wihtout making API calls (ie a mock) as it is transactional. 我想根据一些逻辑与此API进行互动,我希望能够测试逻辑wihtout进行API调用(即模拟),因为它是事务性的。

Clearly I need to mock out (at some stage) some of the API client's functionality, but I'm unsure how best to go about this. 显然,我需要(在某个阶段)模拟一些API客户端的功能,但是我不确定如何最好地做到这一点。

Should I simply extend the APIClient class, implement my logic and then extend my class again to create a mock version: 我应该简单地扩展APIClient类,实现我的逻辑,然后再次扩展我的类以创建模拟版本:

class MyClass(APIClient):
   pass #Lots of interesting things actually happen here

class MyTestClass(MyClass):

   def an_overridden_method(self):
      pass #here I implement a method for testing

Or should I pass an APIClient instance to my class and, when I want to test, should I pass in a mocked out version of the APIClient class? 还是应该将APIClient实例传递给我的类,并且在我想进行测试时,应该传递APIClient类的APIClient版本吗?

class MyClass(object):

   def __init__(self, api_client):
      self.api_client = api_client

class MockAPIClient(APIClient):

   def an_overwritten_method(self):
      pass

Or is there an alernative, 'best practice' way for me to implement this? 还是我有一种替代性的“最佳实践”方法来实现这一目标?

You would normally not mock parts of the unit under test. 通常,您不会嘲笑被测单元的各个部分。 If you're testing MyClass , one of the things you would like to test is that it creates and executes transactions when it's really supposed to do that. 如果您正在测试MyClass ,那么您要测试的一件事就是它确实可以创建和执行事务。 The overridden method, in your example, would go un-tested. 在您的示例中,重写的方法将未经测试。

Instead, you should mock the layer that would actually cause transactions to occur; 相反,您应该模拟实际上会导致交易发生的图层; arrange for SomeDatabaseApi.connect , SomeDatabaseApi.Connection.startTransaction and so on to actually be mock stubs, so that the unit under tests still calls them, but then you can see how they were called afterwards. 安排SomeDatabaseApi.connectSomeDatabaseApi.Connection.startTransaction等实际上是模拟存根,以便被测试的单元仍然调用它们,但是随后您可以看到它们如何被调用。

There's probably more more mock testing frameworks for python than you could possibly need, but I've made good use of MiniMock , it's simple, effective and expressive. 用于python的模拟测试框架可能比您可能需要的更多,但是我充分利用了MiniMock ,它简单,有效且富有表现力。

+1 for passing in the api_client instance; +1用于传递api_client实例; keeps thinks loosely coupled. 保持思想松散耦合。

Also, depending on the APIClient class, I would create a completely new class, without inheriting from the original APIClient . 另外,根据APIClient类,我将创建一个全新的类,而不继承原始APIClient

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM