Mocking Boto3 with pytest

Alex O'Callaghan

使用 pytest 模擬 Boto3

原文由 Alex O'Callaghan 發布,訂閱此部落格

當你使用 boto3 Python 函式庫撰寫會與 S3 或 DynamoDB 等 AWS 服務互動的單元測試時,你會想要模擬這些請求。你可以使用 botocore Stubber 來達成這個目的。

假設有一個用來查詢 DynamoDB 項目的函式:

import boto3

def get_item(id):
  dynamodb = boto3.client("dynamodb")
  response = dynamodb.get_item(
    TableName="item_table",
    Key={"id": id}
  )
  return response.get("Item")

你可以使用 pytest 搭配 botocore.stub 來撰寫單元測試以模擬這些請求:

import boto3
from botocore.stub import Stubber

from my_project import get_item

def test_get_item(mocker):
  dynamodb = boto3.client("dynamodb")
  stubber = Stubber(dynamodb)

  stubber.add_response(
    "get_item",
    {"hello": "world"},
    {"TableName": "item_table", "Key": {"id": "hello-world"}}
  )

  with mocker.patch(
    "boto3.client", return_value=dynamodb
  ):
    with stubber:
      result = get_item("hello-world")

      assert result["hello"] == "world"
  • add_response 呼叫會為 get_item 呼叫加入 {"hello": "world"} 的模擬回應,同時也會驗證傳入的參數是否符合預期
  • with stubber: 會啟用 Stubber —— 你也可以在設定好模擬回應後呼叫 stubber.activate()

你也可以將 stubber 與 boto3.resource API 一起使用:

import boto3

def get_item(id):
  dynamodb = boto3.resource("dynamodb")
  table = dynamodb.Table("item_table")
  response = table.get_item(
    Key={"id": id}
  )
  return response.get("Item")
import boto3
from botocore.stub import Stubber

from my_project import get_item

def test_get_item(mocker):
  dynamodb = boto3.resource("dynamodb")
  stubber = Stubber(dynamodb.meta.client) # Access the client through `meta`

  stubber.add_response(
    "get_item",
    {"hello": "world"},
    {"TableName": "item_table", "Key": {"id": "hello-world"}}
  )

  with mocker.patch(
    "boto3.resource", return_value=dynamodb
  ):
    with stubber:
      result = get_item("hello-world")

      assert result["hello"] == "world"

延伸閱讀

本文章由 muse-spark-1.2-contributor 進行翻譯

留言