Skip to content

Instantly share code, notes, and snippets.

@b0bu
Last active July 1, 2022 21:24
Show Gist options
  • Save b0bu/660a86e21016479aa7ae1803a8910f56 to your computer and use it in GitHub Desktop.
Save b0bu/660a86e21016479aa7ae1803a8910f56 to your computer and use it in GitHub Desktop.
monkey patch vs dependency injection

monkey patch

from pytest import MonkeyPatch
import boto3

@mock_codebuild
def test_start_project(monkeypatch: MonkeyPatch) -> None:
    client = boto3.client("codebuild")

     def account_id(self) -> str:
         ACCOUNT_ID = "123456789012"
         return ACCOUNT_ID
         
    #  replace account_id() completely
    monkeypatch.setattr(CodeBuildProject, "account_id", account_id)
    code_build_project = CodeBuildProject(interface)

    response = code_build_project.start()

dependency injection

import boto3

class UtilsMock:
  def account_id(self) -> str:
      ACCOUNT_ID = "123456789012"
      return ACCOUNT_ID

@mock_codebuild
def test_start_project() -> None:
  client = boto3.client("codebuild")

  code_build_project = CodeBuildProject(interface)
  
  # inject the implementation details of account_id
  response = code_build_project.start(UtilsMock())
from botocore.exceptions import ClientError

class Utils(Protocol):
   def __init__(self):
       self.sts_client = StsClient().client
       
   def account_id(self) -> str:
       try:
           response: dict[str, str] = self.sts_client.get_caller_identity()
       except ClientError as err:
           print("Error from sts_client.get_caller_identiy() function")
           raise err

       account_id: str = response["Account"]
       return account_id
       
class CodeBuildProject(object):
   """ use an instance of a codebase to set up codebuild project metadata """
   codebase: Event

   def __init__(self, codebase) -> None:
       self.project_name = codebase.project_name
       self.branch = codebase.branch
       self.client = CodeBuildClient().client
       self.url = str()

   def start(self, util: Utils) -> dict[str,str]:
       """ start a codebuild instances by branch """

       try:
           response: dict[str, str] = self.client.start_build(
               projectName=self.project_name,
               sourceVersion=self.branch,
               )
           assert response["ResponseMetadata"]["HTTPStatusCode"] == 200
           id: str = response["build"]["id"]
           uuid: str = id.split(":")[1]
           print(f"{id} started with source {self.branch} at url:")
       except ClientError as err:
           print("Error from client('codebuild').start_build() function")
           raise err
       
       account_id = util.account_id()
       self.url =  f"https://eu-west-2.console.aws.amazon.com/codesuite/codebuild/{account_id}/projects/\
{self.project_name}/build/{self.project_name}%3A{uuid}/?region=eu-west-2"
       return response
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment