0
# Request Matchers
1
2
Advanced request matching capabilities for precise control over which requests are intercepted. Matchers allow you to specify conditions beyond URL and HTTP method, enabling detailed request validation for complex testing scenarios.
3
4
## Capabilities
5
6
### JSON Payload Matching
7
8
Match requests based on JSON body content with support for exact matching or partial matching for flexible test scenarios.
9
10
```python { .api }
11
def json_params_matcher(params, *, strict_match=True):
12
"""
13
Match JSON payload in request body.
14
15
Parameters:
16
- params: dict or list representing expected JSON content
17
- strict_match: bool, if True validates all keys match (default: True)
18
if False, allows additional keys in request
19
20
Returns:
21
Matcher function that validates request JSON payload
22
23
Usage:
24
Match exact JSON:
25
>>> matcher = json_params_matcher({"key": "value"})
26
27
Match partial JSON (allows extra keys):
28
>>> matcher = json_params_matcher({"key": "value"}, strict_match=False)
29
"""
30
```
31
32
**Usage Example:**
33
34
```python
35
from responses.matchers import json_params_matcher
36
37
@responses.activate
38
def test_json_matching():
39
responses.add(
40
responses.POST,
41
"http://api.example.com/users",
42
match=[json_params_matcher({"name": "John", "age": 30})],
43
json={"id": 1, "name": "John", "age": 30},
44
status=201
45
)
46
47
# This will match
48
response = requests.post(
49
"http://api.example.com/users",
50
json={"name": "John", "age": 30}
51
)
52
assert response.status_code == 201
53
```
54
55
### Query Parameter Matching
56
57
Match requests based on URL query parameters with support for exact or partial matching.
58
59
```python { .api }
60
def query_param_matcher(params, *, strict_match=True):
61
"""
62
Match query parameters in request URL.
63
64
Parameters:
65
- params: dict of expected query parameters
66
- strict_match: bool, if True validates all parameters match (default: True)
67
if False, allows additional parameters in request
68
69
Returns:
70
Matcher function that validates request query parameters
71
72
Note: Numeric values are automatically converted to strings for comparison
73
"""
74
```
75
76
**Usage Example:**
77
78
```python
79
from responses.matchers import query_param_matcher
80
81
@responses.activate
82
def test_query_matching():
83
responses.add(
84
responses.GET,
85
"http://api.example.com/search",
86
match=[query_param_matcher({"q": "python", "limit": "10"})],
87
json={"results": ["result1", "result2"]}
88
)
89
90
# This will match
91
response = requests.get("http://api.example.com/search?q=python&limit=10")
92
assert response.status_code == 200
93
```
94
95
### Header Matching
96
97
Match requests based on HTTP headers with support for exact values or regex patterns.
98
99
```python { .api }
100
def header_matcher(headers, strict_match=False):
101
"""
102
Match HTTP headers in request.
103
104
Parameters:
105
- headers: dict of header name to expected value or regex Pattern
106
- strict_match: bool, if True request must have exactly these headers
107
if False, allows additional headers (default: False)
108
109
Returns:
110
Matcher function that validates request headers
111
112
Note: Standard headers added by requests library are ignored unless strict_match=True
113
"""
114
```
115
116
**Usage Example:**
117
118
```python
119
from responses.matchers import header_matcher
120
import re
121
122
@responses.activate
123
def test_header_matching():
124
responses.add(
125
responses.POST,
126
"http://api.example.com/data",
127
match=[header_matcher({
128
"Authorization": "Bearer token123",
129
"User-Agent": re.compile(r"MyApp/\d+\.\d+")
130
})],
131
json={"success": True}
132
)
133
134
# This will match
135
response = requests.post(
136
"http://api.example.com/data",
137
headers={
138
"Authorization": "Bearer token123",
139
"User-Agent": "MyApp/1.0"
140
}
141
)
142
assert response.json()["success"] is True
143
```
144
145
### Body Content Matching
146
147
Match requests based on exact body content for non-JSON payloads.
148
149
```python { .api }
150
def body_matcher(params, *, allow_blank=False):
151
"""
152
Match exact request body content.
153
154
Parameters:
155
- params: str representing expected body content
156
- allow_blank: bool, whether to allow blank/empty body content
157
158
Returns:
159
Matcher function that validates request body content
160
"""
161
```
162
163
### URL-Encoded Form Data Matching
164
165
Match requests with URL-encoded form data (application/x-www-form-urlencoded).
166
167
```python { .api }
168
def urlencoded_params_matcher(params, *, allow_blank=False):
169
"""
170
Match URL-encoded form data in request body.
171
172
Parameters:
173
- params: dict of expected form data
174
- allow_blank: bool, whether to allow blank values in form data
175
176
Returns:
177
Matcher function that validates form data content
178
"""
179
```
180
181
**Usage Example:**
182
183
```python
184
from responses.matchers import urlencoded_params_matcher
185
186
@responses.activate
187
def test_form_data_matching():
188
responses.add(
189
responses.POST,
190
"http://api.example.com/form",
191
match=[urlencoded_params_matcher({"username": "john", "password": "secret"})],
192
json={"login": "success"}
193
)
194
195
# This will match
196
response = requests.post(
197
"http://api.example.com/form",
198
data={"username": "john", "password": "secret"}
199
)
200
assert response.json()["login"] == "success"
201
```
202
203
### Query String Matching
204
205
Match the exact query string portion of the URL.
206
207
```python { .api }
208
def query_string_matcher(query):
209
"""
210
Match exact query string in request URL.
211
212
Parameters:
213
- query: str representing expected query string (without '?')
214
215
Returns:
216
Matcher function that validates query string
217
218
Note: Parameters are sorted before comparison for consistent matching
219
"""
220
```
221
222
### Request Keyword Arguments Matching
223
224
Match additional request parameters like timeout, verify, etc.
225
226
```python { .api }
227
def request_kwargs_matcher(kwargs):
228
"""
229
Match keyword arguments passed to the request function.
230
231
Parameters:
232
- kwargs: dict of expected keyword arguments
233
234
Returns:
235
Matcher function that validates request kwargs
236
237
Common kwargs: timeout, verify, cert, proxies, stream, allow_redirects
238
"""
239
```
240
241
### Multipart Form Data Matching
242
243
Match requests with multipart/form-data content type, typically used for file uploads.
244
245
```python { .api }
246
def multipart_matcher(files, data=None):
247
"""
248
Match multipart/form-data requests.
249
250
Parameters:
251
- files: dict of file data (same format as requests files parameter)
252
- data: dict of additional form fields (optional)
253
254
Returns:
255
Matcher function that validates multipart content
256
257
Raises:
258
TypeError if files parameter is empty
259
"""
260
```
261
262
**Usage Example:**
263
264
```python
265
from responses.matchers import multipart_matcher
266
267
@responses.activate
268
def test_file_upload():
269
responses.add(
270
responses.POST,
271
"http://api.example.com/upload",
272
match=[multipart_matcher(
273
files={"file": ("test.txt", "file content", "text/plain")},
274
data={"description": "Test file"}
275
)],
276
json={"uploaded": True}
277
)
278
279
# This will match
280
with open("test.txt", "w") as f:
281
f.write("file content")
282
283
with open("test.txt", "rb") as f:
284
response = requests.post(
285
"http://api.example.com/upload",
286
files={"file": ("test.txt", f, "text/plain")},
287
data={"description": "Test file"}
288
)
289
assert response.json()["uploaded"] is True
290
```
291
292
### Fragment Identifier Matching
293
294
Match URL fragment identifiers (the part after '#' in URLs).
295
296
```python { .api }
297
def fragment_identifier_matcher(identifier):
298
"""
299
Match URL fragment identifier.
300
301
Parameters:
302
- identifier: str representing expected fragment (without '#')
303
304
Returns:
305
Matcher function that validates URL fragment
306
"""
307
```
308
309
## Combining Matchers
310
311
Multiple matchers can be combined to create complex matching conditions. All matchers in the list must pass for the request to match.
312
313
**Usage Example:**
314
315
```python
316
from responses.matchers import json_params_matcher, header_matcher, query_param_matcher
317
318
@responses.activate
319
def test_combined_matching():
320
responses.add(
321
responses.POST,
322
"http://api.example.com/complex",
323
match=[
324
json_params_matcher({"action": "create"}),
325
header_matcher({"Authorization": "Bearer token"}),
326
query_param_matcher({"version": "v1"})
327
],
328
json={"result": "success"}
329
)
330
331
# All matchers must pass
332
response = requests.post(
333
"http://api.example.com/complex?version=v1",
334
json={"action": "create"},
335
headers={"Authorization": "Bearer token"}
336
)
337
assert response.json()["result"] == "success"
338
```