felangel / mocktail

A mock library for Dart inspired by mockito
https://pub.dev/packages/mocktail
MIT License
617 stars 81 forks source link

Less verbose Mock declarations #185

Open alestiago opened 1 year ago

alestiago commented 1 year ago

Problem Currently defining a Mock looks like this:

class _MockDog extends Mock implements Dog {}
final Dog mockDog = _MockDog();

Solution I would like I would like to have a one-line syntax alternative (or completely remove the old syntax):

final Dog mockDog = Mock<Dog>();

The advantages are:

Additional notes I'm willing to work on a pull request for this change if there is an agreement on the new syntax. As far as I am concerned having something exactly like the proposed solution would lead to a breaking change (depends on Dart's current and future capabilities). I'm opened to read about solutions that will avoid introducing a breaking change with the new syntax. I believe that a breaking change can be justified since the new syntax has many advantages and solves a couple of problems (as outlined in Additional Context).

felangel commented 1 year ago

Hi @alestiago thanks for opening the issue!

Do you have an idea for what the implementation would look like? I don’t see how you would be able to achieve the following:

final Dog mockDog = Mock<Dog>();

because you would be creating an instance of a Mock and if that object doesn’t extend or implement Dog, it cannot be assigned to a variable of type Dog unless I’m missing something.

Do you have a simple POC to illustrate how this proposal would be implemented?

Thanks again!

alestiago commented 1 year ago

@felangel I don't have a POC to illustrate how the one line example syntax can be implemented (I tried though). I think it is not possible in Dart 2.19.0 without code generation and/or mirrors.

The most obvious solution would be to do as follows, but is currently not possible to do:

class Mock<T> implements T {}

The one liner final Dog mockDog = Mock<Dog>() is what I would wish to have; but anything that results in a single line that satisfies final Dog mockDog = *; (where * denotes any expression) would suffice as long as mockDog is mockable and no code generation (build runner) is required.

Regardless of it being currently possible I wanted to open the issue to describe the most ideal scenario. Maybe there exists a way to satisfy the above statement right now that I'm not aware of. Or maybe feature Dart versions allow satisfying the above.

The aim of the issue is to encourage other developers to tackle the problem and to have a written specification of the ideal API for creating mocks.

It would be a dream 🤩 to do something as:

final Dog mockDog = Mock<Dog>();

Thanks for the package 💙 and fast reply!

tenhobi commented 1 year ago

Exploring some options using the upcoming Dart's static generation would be interesting for sure.