Flutter: 如何模拟一个流(stream)

5

我正在使用Bloc模式,现在我要测试UI。我的问题是:如何模拟流? 这是我拥有的代码: 我给RootPage类一个可选的mockBloc值,如果这个mockBloc不为空,我会将它设置为实际的_bloc。

class RootPage extends StatefulWidget {

  final loggedOut;
  final mockBlock;
  RootPage(this.loggedOut, {this.mockBlock});

  @override
  _RootPageState createState() => _RootPageState();
}


class _RootPageState extends State<RootPage> {

  LoginBloc _bloc;

     @override
      void initState() {
        super.initState();
        if (widget.mockBlock != null)
          _bloc = widget.mockBlock;
        else
          _bloc = new LoginBloc();
        if (widget.loggedOut == false)
        _bloc.startLoad.add(null);
      }

    ...

 @override
  Widget build(BuildContext context) {
    return StreamBuilder(
        stream: _bloc.load,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return Column(
                children: <Widget>
                     ...

这是我尝试过的内容:
  testWidgets('MyWidget', (WidgetTester tester) async {
    MockBloc mockBloc = new MockBloc();
    MockTokenApi mockTokenApi = new MockTokenApi();

    await tester.pumpWidget(new MaterialApp(
        home: RootPage(false, mockBlock: mockBloc)));

    when(mockBloc.startLoad.add(null)).thenReturn(mockBloc.insertLoadStatus.add(SettingsStatus.set));   //this will give in output the stream that the StreamBuilder is listening to (_bloc.load)
    });
   await tester.pump();
    expect(find.text("Root"), findsOneWidget);

  });

我所得到的结果总是:

调用了空对象上的 'add' 方法

当调用 _bloc.startLoad.add(null) 时。

在模拟的when()函数中,你调用了mockBloc.insertLoadStatus上的add(),但我没有看到你在哪里或如何定义insertLoadStatus? - Maks
2个回答

1
您可以通过使用mockito创建一个模拟流。下面是一个示例,展示如何实现它。
import 'package:mockito/mockito.dart';

class MockStream extends Mock implements Stream<int> {}

void main() async {
  var stream = MockStream();
  when(stream.first).thenAnswer((_) => Future.value(7));
  print(await stream.first);

  when(stream.listen(any)).thenAnswer((Invocation invocation) {
    var callback = invocation.positionalArguments.single;
    callback(1);
    callback(2);
    callback(3);
  });

  stream.listen((e) async => print(await e));
}

FYI,这里是明显的来源:https://github.com/dart-lang/mockito/issues/223#issuecomment-640286713 - Chuck Batson

0

自从空安全(null safety)出现以来,您可以按照以下方式进行操作:

import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';

import 'test_test.mocks.dart';

@GenerateMocks([Stream])
void main() {
  test('foo', () async {
    var stream = MockStream();

    Stream<int> streamFunc() async* {
      yield 1;
      yield 2;
      yield 3;
    }
    when(stream.listen(
      any,
      onError: anyNamed('onError'),
      onDone: anyNamed('onDone'),
      cancelOnError: anyNamed('cancelOnError'),
    )).thenAnswer((inv) {
      var onData = inv.positionalArguments.single;
      var onError = inv.namedArguments[#onError];
      var onDone = inv.namedArguments[#onDone];
      var cancelOnError = inv.namedArguments[#cancelOnError];
      return streamFunc().listen(onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError);
    });

    stream.listen((e) async => print(await e));
  });
}

来源


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接