Skip to content

Commit 8d7f641

Browse files
committed
✅ add tests for error interception in InterceptedClient
1 parent 7c1847d commit 8d7f641

1 file changed

Lines changed: 213 additions & 0 deletions

File tree

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
import 'package:http_interceptor/http_interceptor.dart';
2+
import 'package:test/test.dart';
3+
4+
void main() {
5+
group('InterceptedClient error interception', () {
6+
late _MockInterceptor mockInterceptor;
7+
late InterceptedClient client;
8+
9+
setUp(() {
10+
mockInterceptor = _MockInterceptor();
11+
client = InterceptedClient.build(interceptors: [mockInterceptor]);
12+
});
13+
14+
test(
15+
'interceptors are called when an error occurs',
16+
() async {
17+
final request = Request('GET', Uri.parse('https://example.com'));
18+
final error = Exception('Test error');
19+
final stackTrace = StackTrace.current;
20+
21+
mockInterceptor.shouldInterceptErrorResult = true;
22+
23+
// Call the internal _interceptError method indirectly
24+
// by creating a scenario where it would be called
25+
await _callInterceptError(
26+
client: client,
27+
request: request,
28+
error: error,
29+
stackTrace: stackTrace,
30+
);
31+
32+
expect(mockInterceptor.interceptErrorCalled, true);
33+
expect(mockInterceptor.lastRequest, isNotNull);
34+
expect(mockInterceptor.lastError, isNotNull);
35+
expect(mockInterceptor.lastStackTrace, isNotNull);
36+
},
37+
);
38+
39+
test(
40+
'interceptors are not called when shouldInterceptError returns false',
41+
() async {
42+
final request = Request('GET', Uri.parse('https://example.com'));
43+
final error = Exception('Test error');
44+
final stackTrace = StackTrace.current;
45+
46+
mockInterceptor.shouldInterceptErrorResult = false;
47+
48+
await _callInterceptError(
49+
client: client,
50+
request: request,
51+
error: error,
52+
stackTrace: stackTrace,
53+
);
54+
55+
expect(mockInterceptor.interceptErrorCalled, false);
56+
},
57+
);
58+
59+
test('multiple interceptors are called when an error occurs', () async {
60+
final request = Request('GET', Uri.parse('https://example.com'));
61+
final error = Exception('Test error');
62+
final stackTrace = StackTrace.current;
63+
64+
final mockInterceptor2 = _MockInterceptor();
65+
66+
client = InterceptedClient.build(
67+
interceptors: [mockInterceptor, mockInterceptor2],
68+
);
69+
70+
mockInterceptor.shouldInterceptErrorResult = true;
71+
mockInterceptor2.shouldInterceptErrorResult = true;
72+
73+
await _callInterceptError(
74+
client: client,
75+
request: request,
76+
error: error,
77+
stackTrace: stackTrace,
78+
);
79+
80+
expect(mockInterceptor.interceptErrorCalled, true);
81+
expect(mockInterceptor2.interceptErrorCalled, true);
82+
});
83+
84+
test('interceptors receive the correct parameters', () async {
85+
final request = Request('GET', Uri.parse('https://example.com'));
86+
final error = Exception('Test error');
87+
final stackTrace = StackTrace.current;
88+
89+
mockInterceptor.shouldInterceptErrorResult = true;
90+
91+
await _callInterceptError(
92+
client: client,
93+
request: request,
94+
error: error,
95+
stackTrace: stackTrace,
96+
);
97+
98+
expect(mockInterceptor.lastRequest, isNotNull);
99+
expect(mockInterceptor.lastError.toString(), contains('Test error'));
100+
expect(mockInterceptor.lastStackTrace, isNotNull);
101+
});
102+
});
103+
}
104+
105+
/// Helper function to indirectly call the _interceptError method
106+
/// by simulating a scenario where it would be called
107+
Future<void> _callInterceptError({
108+
required InterceptedClient client,
109+
required BaseRequest request,
110+
required Exception error,
111+
required StackTrace stackTrace,
112+
}) async {
113+
// Create a custom interceptor that will call the _interceptError method
114+
// when its interceptRequest method is called
115+
final errorTriggeringInterceptor = _ErrorTriggeringInterceptor(
116+
request: request,
117+
error: error,
118+
stackTrace: stackTrace,
119+
);
120+
121+
// Add the interceptor to the client
122+
final clientWithErrorInterceptor = InterceptedClient.build(
123+
interceptors: [errorTriggeringInterceptor, ...client.interceptors],
124+
);
125+
126+
// Make a request that will trigger the error
127+
try {
128+
await clientWithErrorInterceptor.send(request);
129+
fail('Expected an exception to be thrown');
130+
} catch (e) {
131+
// Exception expected
132+
}
133+
}
134+
135+
/// Custom interceptor that throws a controlled exception during request interception
136+
class _ErrorTriggeringInterceptor implements InterceptorContract {
137+
final BaseRequest request;
138+
final Exception error;
139+
final StackTrace stackTrace;
140+
141+
const _ErrorTriggeringInterceptor({
142+
required this.request,
143+
required this.error,
144+
required this.stackTrace,
145+
});
146+
147+
@override
148+
BaseRequest interceptRequest({required BaseRequest request}) => throw error;
149+
150+
@override
151+
BaseResponse interceptResponse({required BaseResponse response}) => response;
152+
153+
@override
154+
bool shouldInterceptRequest({required BaseRequest request}) => true;
155+
156+
@override
157+
bool shouldInterceptResponse({required BaseResponse response}) => false;
158+
159+
@override
160+
bool shouldInterceptError({BaseRequest? request, BaseResponse? response}) =>
161+
false;
162+
163+
@override
164+
void interceptError({
165+
BaseRequest? request,
166+
BaseResponse? response,
167+
Exception? error,
168+
StackTrace? stackTrace,
169+
}) {
170+
// Do nothing
171+
}
172+
}
173+
174+
/// Mock interceptor for testing
175+
class _MockInterceptor implements InterceptorContract {
176+
bool shouldInterceptErrorResult = true;
177+
bool interceptErrorCalled = false;
178+
179+
BaseRequest? lastRequest;
180+
BaseResponse? lastResponse;
181+
Exception? lastError;
182+
StackTrace? lastStackTrace;
183+
184+
@override
185+
BaseRequest interceptRequest({required BaseRequest request}) => request;
186+
187+
@override
188+
BaseResponse interceptResponse({required BaseResponse response}) => response;
189+
190+
@override
191+
bool shouldInterceptError({BaseRequest? request, BaseResponse? response}) =>
192+
shouldInterceptErrorResult;
193+
194+
@override
195+
void interceptError({
196+
BaseRequest? request,
197+
BaseResponse? response,
198+
Exception? error,
199+
StackTrace? stackTrace,
200+
}) {
201+
interceptErrorCalled = true;
202+
lastRequest = request;
203+
lastResponse = response;
204+
lastError = error;
205+
lastStackTrace = stackTrace;
206+
}
207+
208+
@override
209+
bool shouldInterceptRequest({required BaseRequest request}) => true;
210+
211+
@override
212+
bool shouldInterceptResponse({required BaseResponse response}) => true;
213+
}

0 commit comments

Comments
 (0)