如何初始化差异 class 并在 flutter 中测试小部件时访问其数据?

How to initalize a diffrent class and access its data while widget testing in flutter?

所以我正在开发一个 flutter 应用程序,我使用手机的高度和宽度来决定填充。

我将所有尺寸配置存储在 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;
  }
}

我正在 splash_screen.dart

中初始化 SizeConfig class
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(
      ...
    );
  }
}

我使用 signup_screen.dart 中的宽度,就像这样

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: ...
    );
  }
}

一切正常,但问题是在我测试小部件时出现的。我应该如何调用 init 方法并确保 SizeConfig.screenWidth 的值不为空。 这是我的 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);
  });
}

我尝试查找 MockBuildContext 但据我所知,它仅用于在测试以 BuilContext 作为参数的方法时通过。

这是我得到的错误,它说 SizeConfig.screenWidth 为 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

提前致谢!

由于宽度和高度在SizeConfig中是静态的class,可以直接设置,例如测试

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);
  });
}

或者您可以为设置 SizeConfig 高度和宽度的测试创建一个帮助程序 class,并使用此帮助程序函数创建测试小部件

class HelperFunctions {
  static Widget createWidgetForTesting({Widget child}) {
    SizeConfig.screenHeight = 400;
    SizeConfig.screenWidth = 760;
    SizeConfig.orientation = Orientation.portrait;

    return MaterialApp(
      home: child,
      onGenerateRoute: router.generateRoute,
    );
  }
}