setupResponse function
Sets up a mock HTTP response with the given headers and body.
This function creates a MockHttpResponse instance and configures it with the provided headers and body. It sets up the necessary mocks for the response's status code, headers, and body handling methods.
The returned MockHttpResponse instance can be used in tests to simulate an HTTP response.
Parameters:
headers: An optional map of headers to set on the response.body: An optional BytesBuilder to capture the response body.
Returns: The configured MockHttpResponse instance.
Implementation
MockHttpResponse setupResponse({
Map<String, List<String>>? headers,
List<Cookie>? cookies,
BytesBuilder? body,
}) {
final mockResponse = MockHttpResponse();
headers ??= {};
body ??= BytesBuilder();
// Track real HttpResponse-like state
var headersSent = false;
var bodyStarted = false;
var closed = false;
void ensureHeadersNotSent() {
if (headersSent || bodyStarted || closed) {
throw StateError('Header already sent');
}
}
void ensureNotClosed() {
if (closed) {
throw StateError('Response is closed');
}
}
// Setup cookies
if (cookies != null && cookies.isNotEmpty) {
headers[HttpHeaders.cookieHeader] = cookies
.map((cookie) => '${cookie.name}=${cookie.value}')
.toList();
}
headers.remove(HttpHeaders.cookieHeader);
// Create a synced cookie list that automatically updates headers
final syncedCookieList = SyncedCookieList([...?cookies], headers);
when(mockResponse.cookies).thenAnswer((_) => syncedCookieList);
int statusCode = HttpStatus.ok;
final mockResponseHeaders = setupHeaders(headers);
when(mockResponse.statusCode).thenAnswer((_) => statusCode);
when(mockResponse.statusCode = any).thenAnswer((invocation) {
ensureHeadersNotSent();
statusCode = invocation.positionalArguments.first as int;
});
// Mock headers getter and setup headers
when(mockResponse.headers).thenAnswer((i) => mockResponseHeaders);
// write/add/addStream mark body started and implicitly send headers
when(mockResponse.write(any)).thenAnswer((invocation) {
ensureNotClosed();
headersSent = true;
bodyStarted = true;
final data = invocation.positionalArguments[0].toString();
body?.add(utf8.encode(data));
});
when(mockResponse.addStream(any)).thenAnswer((invocation) async {
ensureNotClosed();
headersSent = true;
bodyStarted = true;
final stream = invocation.positionalArguments[0] as Stream<List<int>>;
await for (final chunk in stream) {
body?.add(chunk);
}
});
when(mockResponse.add(any)).thenAnswer((invocation) {
ensureNotClosed();
headersSent = true;
bodyStarted = true;
final data = invocation.positionalArguments[0] as List<int>;
body?.add(data);
});
// Mock close method to finalize the response
when(mockResponse.close()).thenAnswer((_) async {
ensureNotClosed();
headersSent = true;
closed = true;
});
return mockResponse;
}