Riverpod Stream Provider Testing in Pure Dart

163 Views Asked by At

I'm struggling with writing a test for a Stream Provider. It can obviously be done, but I'm kind of new to using Mocks, and I haven't figured out a way to get it to work. Here's what I have so far:

@Riverpod(keepAlive: true)
class AtFhirListen extends _$AtFhirListen {
  @override
  Stream<AtFhirNotification> build(AtClient atClient) async* {
    atClient.notificationService
        .subscribe(shouldDecrypt: true)
        .map((AtNotification atNotification) async* {
      if (atNotification.value != null) {
        try {
          final AtFhirNotification atFhirNotification =
              AtFhirNotification.fromJsonString(atNotification.value!);
          yield atFhirNotification;
        } catch (exception) {
          // TODO(Dokotela): what do to with this error
        }
      }
    });
  }
}

And then:

class MockAtClient extends Mock implements AtClient {
  @override
  final NotificationService notificationService = MockNotificationService();
}

class MockNotificationService extends Mock implements NotificationService {
  @override
  Stream<AtNotification> subscribe({String? regex, bool? shouldDecrypt}) {
    return Stream<AtNotification>.fromIterable(<AtNotification>[
      AtNotification('id1', 'key1', '@from1', '@to1', 12345, 'text', true),
      AtNotification('id2', 'key2', '@from2', '@to2', 12345, 'text', true,
          value: Dstu2ResourceNotification(
                  dstu2.Patient(fhirId: dstu2.FhirId('id2')))
              .toJsonString()),
      AtNotification('id3', 'key3', '@from3', '@to3', 12345, 'text', true),
      AtNotification('id4', 'key4', '@from4', '@to4', 12345, 'text', true),
    ]);
  }
}

void main() {
  final MockAtClient atClient = MockAtClient();
  group('AtFhirListen', () {
    test('should return AtFhirNotification', () async {
      final Stream<AtFhirNotification> stream = AtFhirListen().build(atClient);
      expect(
          await stream.first,
          AtFhirNotification.dstu2Resource(
              dstu2.Patient(fhirId: dstu2.FhirId('id2'))));
    });
  });
}

Which gives me a bad state, no element error. I've also tried to follow the tutorial here, which I thought would give me something like this:

void main() {
  group('AtFhirListen', () {
    test('should return AtFhirNotification', () async {
      final MockAtClient atClient = MockAtClient();
      final ProviderContainer container = ProviderContainer();
      final Listener<AsyncValue<AtFhirNotification>> listener =
          Listener<AsyncValue<AtFhirNotification>>();

      container.listen(
        atFhirListenProvider(atClient),
        listener,
        fireImmediately: true,
      );
      verify(
        () => listener(
            null,
            AsyncData<AtFhirNotification>(
              Dstu2ResourceNotification(
                  dstu2.Patient(fhirId: dstu2.FhirId('id2'))),
            )),
      );
    });
  });
}

But then that gives me an error of: TestFailure (Used on a non-mockito object). As I said, I'm new to using Mockito, so pointers on what I'm doing wrong would be appreciated.

0

There are 0 best solutions below