Unit testing in Flutter passing BuildContext
One way is to use testWidgets
in combination with a Builder
widget:
testWidgets('me testing', (WidgetTester tester) async { await tester.pumpWidget( Builder( builder: (BuildContext context) { var actual = sut.myMethodName(context, ...); expect(actual, something); // The builder function must return a widget. return Placeholder(); }, ), );});
You can actually mock the BuildContext
so the test will run headless. I think it's better but might be not a solution that you are looking for.
BuildContext
is an abstract class therefore it cannot be instantiated. Any abstract class can be mocked by creating implementations of that class. If I take your example then the code will look like this:
class MockBuildContext extends Mock implements BuildContext {}void main() { MyClass sut; MockBuildContext _mockContext; setUp(() { sut = MyClass(); _mockContext = MockBuildContext(); }); test('me testing', () { var actual = sut.myMethodName(_mockContext, ...); expect(actual, something); });}
Here is a simple way to retrieve a BuildContext instance inside a test case:
testWidgets('showDialog', (WidgetTester tester) async { await tester.pumpWidget(MaterialApp(home: Material(child: Container()))); final BuildContext context = tester.element(find.byType(Container)); final dialog = showDialog( context: context, builder: (context) => AlertDialog( content: Text('shown by showDialog'), ), ); // apply your tests to dialog or its contents here.});
This was inspired by Simple dialog control test from the Flutter test cases for the showDialog()
function.
The whole "app" consist of a Container
widget in a MaterialApp
frame. The BuildContext
instance is retrieved form by finding the Element
instance related to the Container
.