Dependency Injection and Testing

Search for a command to run...

No comments yet. Be the first to comment.
Here we will cover various aspects of unit, widget and integration testing in Flutter
Recently I had to implement image uploading which required form data that cannot be done with the standard http.Clientand instead needs http.MultipartRequest. We have been doing a big push to implement a proper TDD approach in our products over at Wy...
The Problem Wasn’t Triage Most AI workflows in software engineering still keep the human directly in the middle of triage. The AI might help write code. It might explain a stack trace. It might summar

There’s been a steady undercurrent of people switching tools lately. Copilot to Claude. Claude to something else. Codex quietly entering more workflows. A lot of confidence in different directions, of

It’s been said to me that at times my responses can come across as a “no” first-unintentionally, of course, but real all the same. Not long ago, someone on my team shared an idea they were exploring. I began with a caution, meaning to help them avoid...

The opening sentence of any message often carries more weight than everything that follows. I’ve learned this the hard way. Recently, a report shared something he wanted to pursue. I was supportive — I really was — but my first response came as a cau...

One of the things I’ve always been comfortable with is admitting when I don’t know something. To me, it’s one of the real distinctions between the more and less experienced engineers — and honestly, people in general. When you’re earlier in your care...

Using dependency injection can be great for simplifying your code and keeping it DRY, it can also simplify testing and even improve testability.
If you have not started using dependency injection in your app, you may want to take a look at get_it.
For those already using it, this is how you would go about testing your code that implements these injections.
class DateTimeHelpers {
int nowInMilliseconds() => DateTime.now().millisecondsSinceEpoch;
}
That is a small helper I created for use within various UI’s pull-to-refresh logic to track a last updated value to ensure the spinner goes away incase the API data has not changed.
Obviously not essential to have a simple helper as part of the dependency injection but as all our BloC’s, Cubits, Use Cases, Repositories, etc already is it just keeps in line with the current code-styling.
If used in a widget, it would be accessed as:
sl<DateTimeHelpers>().nowInMilliseconds()
Where sl is a assigned toGetIt.instance.
For testing, you would simply use a mocked class:
class MockDateTimeHelpers extends Mock implements DateTimeHelpers {}
Now if you were using this in say a bloc you would not need to also mock the dependency injection, you would simply provide the MockClass to your test BLoC, however, if you were to use this in a Widget which would be unlikely for this specific helper, you would need to add a few extra lines to your testing code.
You would need to initialize your dependencies within your test, same as you would have done in your application code.
setUp(() {
// Setup the application services
di.initServices();
di.sl.allowReassignment = true;
});
Within your tests setUp method you would initialize your dependencies and then beneath that you enable allowReassignment. That, as the name suggests allows you to reassign your dependencies.
You can then register a new dependency using your mocked class:
mockDateTimeHelpers = MockDateTimeHelpers();
sl.registerSingleton<DateTimeHelpers>(mockDateTimeHelpers);
This will ensure your code runs, and if you need to control the returned value during your tests you can simply use the when from Mokito to return a value of your choosing.
when(mockDateTimeHelpers.nowInMilliseconds).thenReturn(100);
Then for that test or tests, depending on where you added that you can then expect that 100 to be returned whenever the Widget uses that helper.
I hope you found this interesting, and if you have any questions, comments, or improvements, feel free to drop a comment. Enjoy your Flutter development journey :D
If you liked it, a like would be awesome, and if you really liked it, a cup of coffee would be great.
Thanks for reading.