Skip to content

Instantly share code, notes, and snippets.

@MelbourneDeveloper
Created October 28, 2023 09:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MelbourneDeveloper/8b8dd5f7bd96ae3abb4e91717797e46c to your computer and use it in GitHub Desktop.
Save MelbourneDeveloper/8b8dd5f7bd96ae3abb4e91717797e46c to your computer and use it in GitHub Desktop.
Flutter Fake HttpClient
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
void main() => HttpOverrides.runWithHttpOverrides(
() => runApp(
const MainApp(),
),
FakeHttpOverrides(),
);
class _MainAppState extends State<MainApp> {
var text = 'Loading...';
Future<void> loadData() async {
final request = await HttpClient().getUrl(Uri.parse('https://google.com'));
final response = await request.close();
final body = await response.transform(utf8.decoder).join();
setState(() {
text = body;
});
}
@override
Widget build(BuildContext context) => MaterialApp(
home: Scaffold(
body: Center(
child: Text(text),
),
),
);
@override
void initState() {
super.initState();
unawaited(loadData());
}
}
class MainApp extends StatefulWidget {
const MainApp({super.key});
@override
State<MainApp> createState() => _MainAppState();
}
class FakeClient implements HttpClient {
@override
bool autoUncompress = true;
@override
Duration? connectionTimeout;
@override
Duration idleTimeout = const Duration(seconds: 15);
@override
int? maxConnectionsPerHost;
@override
String? userAgent;
@override
void addCredentials(
Uri url, String realm, HttpClientCredentials credentials) {
// TODO: implement addCredentials
}
@override
void addProxyCredentials(
String host, int port, String realm, HttpClientCredentials credentials) {
// TODO: implement addProxyCredentials
}
@override
set authenticate(
Future<bool> Function(Uri url, String scheme, String? realm)? f) {
// TODO: implement authenticate
}
@override
set authenticateProxy(
Future<bool> Function(
String host, int port, String scheme, String? realm)?
f) {
// TODO: implement authenticateProxy
}
@override
set badCertificateCallback(
bool Function(X509Certificate cert, String host, int port)? callback) {
// TODO: implement badCertificateCallback
}
@override
void close({bool force = false}) {
// TODO: implement close
}
@override
set connectionFactory(
Future<ConnectionTask<Socket>> Function(
Uri url, String? proxyHost, int? proxyPort)?
f) {
// TODO: implement connectionFactory
}
@override
Future<HttpClientRequest> delete(String host, int port, String path) {
// TODO: implement delete
throw UnimplementedError();
}
@override
Future<HttpClientRequest> deleteUrl(Uri url) {
// TODO: implement deleteUrl
throw UnimplementedError();
}
@override
set findProxy(String Function(Uri url)? f) {
// TODO: implement findProxy
}
@override
Future<HttpClientRequest> get(String host, int port, String path) {
// TODO: implement get
throw UnimplementedError();
}
@override
Future<HttpClientRequest> getUrl(Uri url) async {
return MockHttpClientRequest();
}
@override
Future<HttpClientRequest> head(String host, int port, String path) {
// TODO: implement head
throw UnimplementedError();
}
@override
Future<HttpClientRequest> headUrl(Uri url) {
// TODO: implement headUrl
throw UnimplementedError();
}
@override
set keyLog(Function(String line)? callback) {
// TODO: implement keyLog
}
@override
Future<HttpClientRequest> open(
String method, String host, int port, String path) {
// TODO: implement open
throw UnimplementedError();
}
@override
Future<HttpClientRequest> openUrl(String method, Uri url) {
// TODO: implement openUrl
throw UnimplementedError();
}
@override
Future<HttpClientRequest> patch(String host, int port, String path) {
// TODO: implement patch
throw UnimplementedError();
}
@override
Future<HttpClientRequest> patchUrl(Uri url) {
// TODO: implement patchUrl
throw UnimplementedError();
}
@override
Future<HttpClientRequest> post(String host, int port, String path) {
// TODO: implement post
throw UnimplementedError();
}
@override
Future<HttpClientRequest> postUrl(Uri url) {
// TODO: implement postUrl
throw UnimplementedError();
}
@override
Future<HttpClientRequest> put(String host, int port, String path) {
// TODO: implement put
throw UnimplementedError();
}
@override
Future<HttpClientRequest> putUrl(Uri url) {
// TODO: implement putUrl
throw UnimplementedError();
}
}
class FakeHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) => FakeClient();
}
class MockHttpClientRequest implements HttpClientRequest {
@override
Future<HttpClientResponse> close() {
return Future.value(MockHttpClientResponse());
}
@override
bool bufferOutput = true;
@override
int contentLength = 5;
@override
Encoding encoding = utf8;
@override
bool followRedirects = true;
@override
int maxRedirects = 5;
@override
bool persistentConnection = true;
@override
void abort([Object? exception, StackTrace? stackTrace]) {
// TODO: implement abort
}
@override
void add(List<int> data) {
// TODO: implement add
}
@override
void addError(Object error, [StackTrace? stackTrace]) {
// TODO: implement addError
}
@override
Future addStream(Stream<List<int>> stream) {
// TODO: implement addStream
throw UnimplementedError();
}
@override
// TODO: implement connectionInfo
HttpConnectionInfo? get connectionInfo => throw UnimplementedError();
@override
// TODO: implement cookies
List<Cookie> get cookies => throw UnimplementedError();
@override
// TODO: implement done
Future<HttpClientResponse> get done => throw UnimplementedError();
@override
Future flush() {
// TODO: implement flush
throw UnimplementedError();
}
@override
// TODO: implement headers
HttpHeaders get headers => throw UnimplementedError();
@override
// TODO: implement method
String get method => throw UnimplementedError();
@override
// TODO: implement uri
Uri get uri => throw UnimplementedError();
@override
void write(Object? object) {
// TODO: implement write
}
@override
void writeAll(Iterable objects, [String separator = ""]) {
// TODO: implement writeAll
}
@override
void writeCharCode(int charCode) {
// TODO: implement writeCharCode
}
@override
void writeln([Object? object = ""]) {
// TODO: implement writeln
}
}
class FakeHttpHeaders implements HttpHeaders {
@override
bool chunkedTransferEncoding = false;
@override
int contentLength = 5;
@override
ContentType? contentType;
@override
DateTime? date;
@override
DateTime? expires;
@override
String? host;
@override
DateTime? ifModifiedSince;
@override
bool persistentConnection = false;
@override
int? port;
@override
List<String>? operator [](String name) {
// TODO: implement []
throw UnimplementedError();
}
@override
void add(String name, Object value, {bool preserveHeaderCase = false}) {
// TODO: implement add
}
@override
void clear() {
// TODO: implement clear
}
@override
void forEach(void Function(String name, List<String> values) action) {
// TODO: implement forEach
}
@override
void noFolding(String name) {
// TODO: implement noFolding
}
@override
void remove(String name, Object value) {
// TODO: implement remove
}
@override
void removeAll(String name) {
// TODO: implement removeAll
}
@override
void set(String name, Object value, {bool preserveHeaderCase = false}) {
// TODO: implement set
}
@override
String? value(String name) {
// TODO: implement value
throw UnimplementedError();
}
}
class MockHttpClientResponse extends Stream<List<int>>
implements HttpClientResponse {
@override
int get statusCode => HttpStatus.ok;
@override
HttpHeaders get headers => FakeHttpHeaders();
Stream<List<int>> get content => Stream.fromIterable(
[utf8.encode('You are seeing data from the fake HttpClient')]);
// The HttpClientResponse is also a stream, so we have to implement the "listen" method
@override
StreamSubscription<List<int>> listen(
void Function(List<int> event)? onData, {
Function? onError,
void Function()? onDone,
bool? cancelOnError,
}) {
return content.listen(onData,
onError: onError, onDone: onDone, cancelOnError: cancelOnError);
}
@override
// TODO: implement certificate
X509Certificate? get certificate => throw UnimplementedError();
@override
// TODO: implement compressionState
HttpClientResponseCompressionState get compressionState =>
throw UnimplementedError();
@override
// TODO: implement connectionInfo
HttpConnectionInfo? get connectionInfo => throw UnimplementedError();
@override
// TODO: implement contentLength
int get contentLength => throw UnimplementedError();
@override
// TODO: implement cookies
List<Cookie> get cookies => throw UnimplementedError();
@override
Future<Socket> detachSocket() {
// TODO: implement detachSocket
throw UnimplementedError();
}
@override
// TODO: implement isRedirect
bool get isRedirect => throw UnimplementedError();
@override
// TODO: implement persistentConnection
bool get persistentConnection => throw UnimplementedError();
@override
// TODO: implement reasonPhrase
String get reasonPhrase => throw UnimplementedError();
@override
Future<HttpClientResponse> redirect(
[String? method, Uri? url, bool? followLoops]) {
// TODO: implement redirect
throw UnimplementedError();
}
@override
// TODO: implement redirects
List<RedirectInfo> get redirects => throw UnimplementedError();
// Override other necessary methods with empty implementations...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment