ReactiveX / rxdart

The Reactive Extensions for Dart
http://reactivex.io
Apache License 2.0
3.36k stars 271 forks source link

doOnData causes error when used with mocked object (Mocktail package) #671

Closed artahc closed 2 years ago

artahc commented 2 years ago

Describe the bug Hi, I don't know whether this bugs belong to RxDart or Mocktail. So I put it here first, but if this doesn't belong here, you can close the issue.

So I have Foo class which invoke Future method from mocked Bar. I converted the Future method into Streams, then uses the doOnData operator on the stream. The doOnData causes this error:

type 'DoStreamTransformer<String?>' is not a subtype of type 'StreamTransformer<String, String?>' of 'streamTransformer'

If I remove doOnData, everything works just fine. I haven't test this with any other RxDart's operators

To Reproduce Take a look on this code


class MockBar extends Mock implements Bar {}

class Foo {
  final Bar bar;
  Foo(this.bar);

  Future<String> fetch() async {
    var memory = LazyStream(() {
      return Future.sync(() => bar.fromMemory()).asStream().where((event) => event != null).doOnData((event) {
        print("found from memory");
      });
    });

    var db = LazyStream(() {
      return Future.sync(() => bar.fromDb()).asStream().doOnData(
        (event) {
          print("found from db");
        },
      );
    });

    var result = await ConcatStream([memory, db]).firstWhere((element) => element != null);

    return result!;
  }
}

class Bar {
  FutureOr<String?> fromDb() async {
    return "found";
  }

  FutureOr<String?> fromMemory() async {
    return null;
  }
}

Simple test

test("Test", () async {
    var bar = MockBar();
    var foo = Foo(bar);

    when(() => bar.fromMemory()).thenAnswer((invocation) => null);
    when(() => bar.fromDb()).thenAnswer((invocation) async => "found");

    var result = await foo.fetch();

    expect(result, "found");
  });

Expected behavior Mocked result shouldn't causes error when used with RxDart's doOnData.

Logs Run flutter analyze and attach any output of that command below. If there are any analysis errors, try resolving them before filing this issue.

Paste the output of running flutter doctor -v here.

[√] Flutter (Channel stable, 2.10.3, on Microsoft Windows [Version 10.0.19043.1586], locale en-US)
[√] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[√] Chrome - develop for the web
[!] Visual Studio - develop for Windows (Visual Studio Community 2019 16.10.4)
    X Visual Studio is missing necessary components. Please re-run the Visual Studio installer for the "Desktop development with C++" workload, and
      include these components:
        MSVC v142 - VS 2019 C++ x64/x86 build tools
         - If there are multiple build tool versions available, install the latest
        C++ CMake tools for Windows
        Windows 10 SDK
[√] Android Studio (version 2020.3)
[√] IntelliJ IDEA Community Edition (version 2020.3)
[√] IntelliJ IDEA Community Edition (version 2021.1)
[√] VS Code, 64-bit edition (version 1.65.2)
[√] Connected device (3 available)
[√] HTTP Host Availability
frankpepermans commented 2 years ago

Didn't try any code you posted, but I think the return Type is the culprit here...

Try Future<String?> fetch, or after the where != null, add a .cast

artahc commented 2 years ago

adding .cast() after where did the trick! I wonder why though...

Thank you for your help, that was quick :))