Я использую socket_io_client
v0.9.12 в своем приложении флаттера (до сих пор не использую нулевую безопасность). Я создаю сокетное соединение с моим внутренним сервером при запуске приложения и разрешаю дочерним виджетам доступ к нему с помощью провайдера.
Я пытаюсь начать создавать соединение в конструкторе, чтобы, когда мне нужно будет использовать клиент сокета, он, вероятно, уже был инициализирован.
Это мой класс провайдера, в котором создано подключение к сокету:
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;
}
}
Виджет основного приложения, который у меня есть:
@override
Widget build(BuildContext context) {
return Provider<SocketClient>(
create: (_) => SocketClient(),
builder: (context, _) {
return Scaffold(
...
);
},
);
}
Вот как я пытаюсь использовать клиент сокета:
Future<void> foo(SocketClient socketClient) async {
await socketClient.finishInitializing();
final socket = socketClient.client;
socket.on(eventName, (dynamic uploadDrawingEvent) {
...
});
}
До сих пор все работает нормально. ????
Однако, когда я пытаюсь запустить тесты, зависящие от этого сокет-клиента, я вижу следующую ошибку:
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
продолжает висеть после строки client = await completer.future;
. Это будущее не решено даже после завершения теста (см. ошибку).
Я хотел бы получить идеи о том, как правильно имитировать этот клиент сокета, чтобы избежать этой ошибки.
Я больше склоняюсь к ответу, который издевается над функциональностью клиента сокета, потому что мне нужно написать еще несколько тестов, чтобы охватить обработчики событий.
Заранее спасибо! ????
Есть ли у вас дальше? столкнулся с той же проблемой
К сожалению нет. На данный момент мы написали тесты, используя фиктивный клиент сокета, используя mocktail. Мы предоставляем этот имитированный клиент сокета в виджет при запуске тестов.