I'm using socket_io_client
v0.9.12 in my flutter app (still not using null safety). I am creating a socket connection with my back-end server when the app starts and allow child widgets to access it using a provider.
I am trying to start creating the connection in the constructor so that when I need to use the socket client, it would probably be initialized already.
This is my provider class which has the creation of the socket connection:
class SocketClient {
SocketClient() {
_initializer = initialize();
}
Future _initializer;
/// Socket client
Socket client;
/// Wait until the client is properly connected with the server
Future finishInitializing() => _initializer;
/// Initialize the socket connection with the server
Future initialize() async {
final completer = Completer<Socket>();
final socket = io(
'http://localhost:3000/gateway',
OptionBuilder() //
.setTransports(['websocket'])
.disableAutoConnect()
.setQuery({'token': 'TOKEN'})
.build(),
)..connect();
socket
..onConnect((_) {
completer.complete(socket);
});
client = await completer.future;
}
}
The main app widget I have:
@override
Widget build(BuildContext context) {
return Provider<SocketClient>(
create: (_) => SocketClient(),
builder: (context, _) {
return Scaffold(
...
);
},
);
}
This is how I am trying to use the socket client:
Future<void> foo(SocketClient socketClient) async {
await socketClient.finishInitializing();
final socket = socketClient.client;
socket.on(eventName, (dynamic uploadDrawingEvent) {
...
});
}
Everything works fine up to now. π
However, when I try to run my tests that depend on this socket client, I see the below error:
Pending timers:
Timer (duration: 0:00:20.000000, periodic: false), created:
#0 new FakeTimer._ (package:fake_async/fake_async.dart:284:41)
#1 FakeAsync._createTimer (package:fake_async/fake_async.dart:248:27)
#2 FakeAsync.run.<anonymous closure> (package:fake_async/fake_async.dart:181:19)
#5 Manager.connect (package:socket_io_client/src/manager.dart:232:19)
#6 Manager.open (package:socket_io_client/src/manager.dart:194:41)
#7 Socket.connect (package:socket_io_client/src/socket.dart:104:8)
#8 SocketClient.initialize (package:flutter_app/web/services/socket_provider.dart:48:8)
<asynchronous suspension>
(elided 2 frames from dart:async)
βββ‘ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK βββββββββββββββββββββββββββββββββββββββββββββββββββββ
The following assertion was thrown running a test:
A Timer is still pending even after the widget tree was disposed.
'package:flutter_test/src/binding.dart':
Failed assertion: line 1241 pos 12: '!timersPending'
When the exception was thrown, this was the stack:
#2 AutomatedTestWidgetsFlutterBinding._verifyInvariants (package:flutter_test/src/binding.dart:1241:12)
#3 TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:803:7)
<asynchronous suspension>
(elided 2 frames from class _AssertionError)
...
initialize
function keeps hanging after client = await completer.future;
line. That future is not resolved even after the test is finished (see the error).
I would like to get ideas on how I can mock this socket client properly to avoid this error.
I'm looking more towards an answer which mocks the functionality of the socket client because I have some more tests to write to cover the event handlers.
Thank you in advance! π
SocketClient
? β Aksoyn