Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Test support for BlocObservers #4203

Open
Rodsevich opened this issue Jul 17, 2024 · 14 comments
Open

feat: Test support for BlocObservers #4203

Rodsevich opened this issue Jul 17, 2024 · 14 comments
Labels
needs repro info The issue is missing a reproduction sample and/or steps question Further information is requested waiting for response Waiting for follow up

Comments

@Rodsevich
Copy link

Description

ATM BlocObservers are being overriden in blocTest logic, and I'm not sure they work as expected when errors are thrown in them (for sure they aren't being outputted on the errors: matcher)

Desired Solution

Add another parameter to blocTest with the oberserver they should use, fully functional ones.

Alternatives Considered

I found workarounds (like defining them on build() everytime and using runZoneGuarded in tests), but I think this is a nice to have, and not that hard to implement neither.

@felangel
Copy link
Owner

Hi @Rodsevich 👋
Thanks for opening an issue!

BlocObservers should not be overridden in blocTests. Can you please provide a link to a minimal reproduction sample that demonstrates the issue you're facing and I'm happy to take a closer look, thanks!

@felangel felangel added question Further information is requested waiting for response Waiting for follow up needs repro info The issue is missing a reproduction sample and/or steps labels Jul 17, 2024
@Rodsevich
Copy link
Author

Sure!
This is a workaround working test
And here would be a minimal example of the code changes maybe needed: #4205

@felangel
Copy link
Owner

@Rodsevich I'm still not sure I understand the problem. Can you please provide more context regarding what the specific issue is and ideally provide a minimal reproduction sample? It's not clear what the problem is based on the code you linked to, thanks!

@Rodsevich
Copy link
Author

Rodsevich commented Jul 17, 2024

Sorry, @felangel. I misunderstood your request. I would like to achieve a way of including BlocObserver's behavior in tests, specially when they fail. ATM that's not possible without hard workarounds like the link provided before.
I'd love bloc_test provides the tool for testing that properly, e.g.:

class FailingObserver extends BlocObserver {
  @override
  void onEvent(Bloc<dynamic, dynamic> bloc, Object? event) {
    super.onEvent(bloc, event);
    throw StateError('catch me');
  }
}

blocTest<CounterBloc, int>(
  'should fail on event addition when FailingObserver provided',
  build: () => CounterBloc(),
  act: (bloc) => bloc.add(CounterEvent.increment),
  errors: () => [isA<StateError>()],
  observer: FailingObserver(),
)

I inspired and finished a working proposal in #4205

@felangel
Copy link
Owner

@Rodsevich thanks for the additional context. I'm not sure modifying blocTest makes sense since blocTest is meant to help you unit test your blocs not your BlocObserver. It should be fairly straightforward to unit test a BlocObserver just like any other plain Dart class. Is there anything specifically challenging about using a regular test to test your BlocObserver?

@Rodsevich
Copy link
Author

@felangel thank for your response. The challenge relies on having your BlocObserver solution tested end to end. Take the example I gave you before, how should you test your analytics/logging/etc solution made for BLoCs is working without a test over a BLoC? You wanna ensure your BLoCs will behave as you expect, not your observers.
Something similar should happen with Bloc.transformer... How could you be sure your blocs behave the way you want by just testing a stream transformer?
Maybe I'm not a testing purist but just a pragmatic. For guys like me an optional parameter that defines the observer or transformer of the BLoCs you are making doesn't bothers.

@felangel
Copy link
Owner

felangel commented Jul 26, 2024

@felangel thank for your response. The challenge relies on having your BlocObserver solution tested end to end. Take the example I gave you before, how should you test your analytics/logging/etc solution made for BLoCs is working without a test over a BLoC? You wanna ensure your BLoCs will behave as you expect, not your observers. Something similar should happen with Bloc.transformer... How could you be sure your blocs behave the way you want by just testing a stream transformer? Maybe I'm not a testing purist but just a pragmatic. For guys like me an optional parameter that defines the observer or transformer of the BLoCs you are making doesn't bothers.

Since these are unit tests, I'd argue that you should only be testing the BlocObserver or the Bloc (not both). You also don't need to worry about unit testing the integration since that's already covered by the bloc library's test suite. You can assume that when you set the Bloc.observer that works as expected (because it's handled by the library) and same goes for Bloc.transformer.

Hope that helps!

@Rodsevich
Copy link
Author

The thing is if we should have behavioral changing objects in the unitTesters or not, right? I think this is turning philosophical 🤔. I love it!
Here is an abstraction for arguing the idea:
Suppose you wanna test your ducks; so you make a duckTester. The environment in which the duck moves defines the behavior of the duck, for sure, so I add a setter for the environment in the duckTester parameters. Now your ducks can be tested when they are flying/swimming/walking by defining air/lake/ground with ease. How should I do the testing properly? And if the answer is defining unit tests for flying and air objetcs. How should I change the code for getting a tool for integration testing in the bloc_test repo (or which is it if it already exists, for I didn't find it before)?

@felangel
Copy link
Owner

@Rodsevich BlocObserver shouldn't affect the behavior of blocs though. BlocObserver is a separate component that can observe/react to changes in blocs but generally the behavior of a bloc should not be affected by BlocObserver.

@Rodsevich
Copy link
Author

But they can, can't them? How do you recommend implementing something that tweaks the behavior of all your BLoCs?
I know, the proper word would be an interceptor or something alike. But why making it more complex if "simplicity is the ultimate sophistication"?

@felangel
Copy link
Owner

felangel commented Sep 3, 2024

But they can, can't them? How do you recommend implementing something that tweaks the behavior of all your BLoCs? I know, the proper word would be an interceptor or something alike. But why making it more complex if "simplicity is the ultimate sophistication"?

Can you provide some more context regarding the use-case your have? I'd love to learn more about how you're using BlocObserver, thanks!

@Rodsevich
Copy link
Author

Rodsevich commented Sep 3, 2024

Sure! I want a way of defining analytics on BlocEvents. For that I use this observer that checks if they are present on the events and send 'em.
Please note the Exceptions thrown... I want everything broken if the setup is faulty or something.

@felangel
Copy link
Owner

Sure! I want a way of defining analytics on BlocEvents. For that I use this observer that checks if they are present on the events and send 'em. Please note the Exceptions thrown... I want everything broken if the setup is faulty or something.

Wouldn't it be sufficient to have a unit test to make sure that you are overriding the BlocObserver and then separate unit tests testing your custom BlocObserver?

@Rodsevich
Copy link
Author

If you want to unit test in general your BlocObserver, yes. But if you want to test your BLoCs, I don't think so...
Take the duck example again: I can have a proper Ground object perfectly tested and functional. But when I code I focus on my ducks, and if my business logic of the ducks pretend them to jump on obstacles how can a test that ensures there are obstacles there help me on that purpose?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs repro info The issue is missing a reproduction sample and/or steps question Further information is requested waiting for response Waiting for follow up
Projects
None yet
Development

No branches or pull requests

2 participants