Issue
So I’m developing a flutter app and I’m using the height and width of the mobile to decide the padding.
I’m storing all the size configurations in size_config.dart
import 'package:flutter/material.dart';
class SizeConfig {
static MediaQueryData _mediaQueryData;
static double screenWidth;
static double screenHeight;
static double defaultSize;
static Orientation orientation;
void init(BuildContext context) {
_mediaQueryData = MediaQuery.of(context);
screenWidth = _mediaQueryData.size.width;
screenHeight = _mediaQueryData.size.height;
orientation = _mediaQueryData.orientation;
}
}
I’m initializing the SizeConfig class in my splash_screen.dart
import 'package:flutter/material.dart';
import 'size_config.dart';
class SplashScreen extends StatefulWidget {
const SplashScreen({ Key? key }) : super(key: key);
@override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
@override
Widget build(BuildContext context) {
SizeConfig().init(context);
return MaterialApp(
...
);
}
}
And I’m using the width in signup_screen.dart
like so
import 'package:flutter/material.dart';
import 'size_config.dart';
class SignUpScreen extends StatefulWidget {
const SignUpScreen({Key? key}) : super(key: key);
@override
_SignUpScreenState createState() => _SignUpScreenState();
}
class _SignUpScreenState extends State<SignUpScreen> {
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(
horizontal: SizeConfig.screenWidth * 0.08,
),
child: ...
);
}
}
Everything is working fine but the problem starts when I’m testing the widgets. How I’m I supposed to call the init
method and make sure that the value of SizeConfig.screenWidth
is not null.
Here is my signup_screen_widget_test.dart
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('SignUpScreen rendering test', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
home: SignUpScreen(),
)
);
expect(find.text('Sign Up'), findsOneWidget);
});
}
I tried looking up MockBuildContext
but as far as I know that is only used to pass while testing methods that have BuilContext
as a parameter.
This is the error I’m getting which is saying that SizeConfig.screenWidth
is null
Output for SignupScreen rendering test
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building SignUpScreen(dirty, state:
_SignUpScreenState#de317):
The method '*' was called on null.
Receiver: null
Tried calling: *(0.08)
The relevant error-causing widget was:
SignUpScreen
Thanks in Advance!
Solution
As width and height is static in SizeConfig class, which can set directly for the test for example
void main() {
testWidgets('SignUpScreen rendering test', (WidgetTester tester) async {
SizeConfig.width = 400
SizeConfig.height = 760
await tester.pumpWidget(
MaterialApp(
home: SignUpScreen(),
)
);
expect(find.text('Sign Up'), findsOneWidget);
});
}
or you can create a helper class for the tests which sets the SizeConfig height and width and use this helper function for creating test widgets
class HelperFunctions {
static Widget createWidgetForTesting({Widget child}) {
SizeConfig.screenHeight = 400;
SizeConfig.screenWidth = 760;
SizeConfig.orientation = Orientation.portrait;
return MaterialApp(
home: child,
onGenerateRoute: router.generateRoute,
);
}
}
Answered By – Fahad Ali shaikh
Answer Checked By – David Marino (FlutterFixes Volunteer)