Ilya Maximencko
Ilya Maximencko

Reputation: 651

Where to put Provider/BlocProvider in the widget tree?

At this moment I think the best place to put them is when you create a route. That is because I can easily mock navigator push call. But I'm confused of what I should do when I have some sort of TabScreen with 3 different separate screens which we usually implement without routes. If I put Providers separately into places when we create tabviews, I mean structure will be like that tabs:[ProvidersForScreen1(Screen1), ProvidersForScreen2(Screen2)...], then it seems like we get features in isolation and that's good BUT in that case I can not create TabScreen to test it, because Providers are created inside TabScreen and I can't mock them. Could someone tell me better approaches if you have?

Upvotes: 2

Views: 1265

Answers (1)

yshean
yshean

Reputation: 441

As a rule of thumb you should place each provider at the closest parent. For example, if you have to access something from a value in a provider from all 3 different screens, place the value provider Foo at the parent of all 3 screens.

You still can have your screen-specific providers, wrapping each screen in your TabScreen. Optionally, you can have your screen-specific providers listen and react to the changes in the parent's value provider Foo, when you need.

For testing, you could test your TabScreen and individual screens separately. When testing the TabScreen, mock the shared provider Foo, and continue to use real instances of the screen-specific providers (side note: if you have API calls in the screen-specific providers, remember to wrap your TabScreen with a provider of a mock repository, assuming you call your repository method to make an API call). Likewise, you can test individual screens as usual by wrapping each of them with a provider of a mock instance.

The key is to always put providers as the parent of your view widgets, so that you can wrap your view widgets with providers of mock instances. I have an example repository that shows how I separate the pages and the views in the view folder of each feature, where each page class only contains the providers and the view class, and the view only consumes them. This makes it easier to test your views by wrapping them with a provider that contains mocks.

Upvotes: 4

Related Questions