22
33import contextlib
44import functools
5+ from collections import defaultdict
56from enum import Enum
67from types import TracebackType
7- from typing import Callable , List , Optional , Union
8+ from typing import Callable , Dict , Iterable , List , Optional , Union
89
910import requests_mock
1011
@@ -40,7 +41,7 @@ class HttpMocker(contextlib.ContextDecorator):
4041
4142 def __init__ (self ) -> None :
4243 self ._mocker = requests_mock .Mocker ()
43- self ._matchers : List [HttpRequestMatcher ] = []
44+ self ._matchers : Dict [ SupportedHttpMethods , List [HttpRequestMatcher ]] = defaultdict ( list )
4445
4546 def __enter__ (self ) -> "HttpMocker" :
4647 self ._mocker .__enter__ ()
@@ -55,7 +56,7 @@ def __exit__(
5556 self ._mocker .__exit__ (exc_type , exc_val , exc_tb )
5657
5758 def _validate_all_matchers_called (self ) -> None :
58- for matcher in self ._matchers :
59+ for matcher in self ._get_matchers () :
5960 if not matcher .has_expected_match_count ():
6061 raise ValueError (f"Invalid number of matches for `{ matcher } `" )
6162
@@ -69,9 +70,9 @@ def _mock_request_method(
6970 responses = [responses ]
7071
7172 matcher = HttpRequestMatcher (request , len (responses ))
72- if matcher in self ._matchers :
73+ if matcher in self ._matchers [ method ] :
7374 raise ValueError (f"Request { matcher .request } already mocked" )
74- self ._matchers .append (matcher )
75+ self ._matchers [ method ] .append (matcher )
7576
7677 getattr (self ._mocker , method )(
7778 requests_mock .ANY ,
@@ -129,7 +130,7 @@ def matches(requests_mock_request: requests_mock.request._RequestObjectProxy) ->
129130
130131 def assert_number_of_calls (self , request : HttpRequest , number_of_calls : int ) -> None :
131132 corresponding_matchers = list (
132- filter (lambda matcher : matcher .request == request , self ._matchers )
133+ filter (lambda matcher : matcher .request is request , self ._get_matchers () )
133134 )
134135 if len (corresponding_matchers ) != 1 :
135136 raise ValueError (
@@ -150,7 +151,7 @@ def wrapper(*args, **kwargs): # type: ignore # this is a very generic wrapper
150151 result = f (* args , ** kwargs )
151152 except requests_mock .NoMockAddress as no_mock_exception :
152153 matchers_as_string = "\n \t " .join (
153- map (lambda matcher : str (matcher .request ), self ._matchers )
154+ map (lambda matcher : str (matcher .request ), self ._get_matchers () )
154155 )
155156 raise ValueError (
156157 f"No matcher matches { no_mock_exception .args [0 ]} with headers `{ no_mock_exception .request .headers } ` "
@@ -175,6 +176,10 @@ def wrapper(*args, **kwargs): # type: ignore # this is a very generic wrapper
175176
176177 return wrapper
177178
179+ def _get_matchers (self ) -> Iterable [HttpRequestMatcher ]:
180+ for matchers in self ._matchers .values ():
181+ yield from matchers
182+
178183 def clear_all_matchers (self ) -> None :
179184 """Clears all stored matchers by resetting the _matchers list to an empty state."""
180- self ._matchers = []
185+ self ._matchers = defaultdict ( list )
0 commit comments