mocktail icon indicating copy to clipboard operation
mocktail copied to clipboard

Expose a way to register default responses

Open timcreatedit opened this issue 1 year ago • 6 comments

Is your feature request related to a problem? Please describe. In large projects, it is often cumbersome to have to stub APIs over and over again, especially if you only want to verify when they were called.

Describe the solution you'd like It would be nice to be able to register default responses for certain return types, either per mock, or (even more useful), globally.

Right now, null is returned from every stub by default. It would be nice to be able to do something like

registerDefaultAnswer<Future<void>>((invocation) => Future.value());

// or

registerDefaultAnswer<Future<void>>((invocation) => Future.value(), forMock: myMock);

Describe alternatives you've considered Right now, methods that return void don't need to actively be stubbed, since null is returned by default. It is a bit inconsistent that the same doesn't apply to Future<void> Function(...), this Feature would allow for setting this up in a flutter_test_config.dart file for example.

Since the _defaultResponses mechanism is private, this can't really be implemented in another package like package:mocktailx

Additional context

  • #233 (The recommended solution forces global mocks, which is often not desirable)
  • #77
  • #45

timcreatedit avatar Jan 02 '25 08:01 timcreatedit

We would also love to have this option. Could we do something for it to happen, @felangel? 🙏

tenhobi avatar Jun 09 '25 15:06 tenhobi

We would also love to have this option. Could we do something for it to happen, @felangel? 🙏

I'll look into it again but I don't think it's possible because there's no object that satisfies both void and Future<void> afaik.

felangel avatar Jun 09 '25 15:06 felangel

Can't there be a way to first use stuff that have been registered with when and if nothing is found, have default options for void, Future<void>, and maybe something else? It can even be made as opt-in.

Edit: I now discovered that void functions actually work by default, but since we use mostly Future everywhere, it is still pain for us not having support for them as well.

tenhobi avatar Jun 09 '25 15:06 tenhobi

Can't there be a way to first use stuff that have been registered with when and if nothing is found, have default options for void, Future<void>, and maybe something else? It can even be made as opt-in.

Edit: I now discovered that void functions actually work by default, but since we use mostly Future everywhere, it is still pain for us not having support for them as well.

The problem is noSuchMethod only has access to an invocation (which afaik doesn't include the return type) so we need to be able to return a single value that satisfies both void and Future<void> which doesn't exist as far as I know. The relevant code is: https://github.com/felangel/mocktail/blob/73b4647b38d133c2180f2c5efec53fc9eefe748a/packages/mocktail/lib/src/mocktail.dart#L129

The default value is null which satisfies void but not Future<void>.

I'll look into it some more later today but iirc I looked into this a while back and didn't see a good solution.

felangel avatar Jun 09 '25 15:06 felangel

Aha, I see. Invocation really has no return type so there is probably nothing we can really do to return the correct thing, except some heuristic maybe, but since in Dart there is no convention like putting Async at the end of the method name, it would not work for Dart.

tenhobi avatar Jun 09 '25 16:06 tenhobi

There is a issue about this topic https://github.com/dart-lang/sdk/issues/50696


This could have been solved with macros, which we will not get. But since they are working on speeding up build_runner dramatically, maybe in the future it will be a way how to get more information in general for mocktail to work with, including knowledge about it's interface and the return type.

tenhobi avatar Jun 09 '25 16:06 tenhobi