Dart/Flutter Web:如何编写一个涵盖`kIsWeb==true`的测试



我想运行一个单元测试,它涵盖了可能的情况,web和非web部署。要测试的类的代码基本上如下所示:

class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
if (kIsWeb) {
return Text("I'm web");
} else {
return Text("I'm not web");
}
}
}

kIsWeb是Dart提供的一个常量,用于确定应用程序是否编译为在web上运行。

我当前的测试类实现只能测试非web路径。有没有办法为kIsWeb == true的情况创建一个测试?

试着这样运行测试:

颤振测试——平台铬

很遗憾,此方法可能在某些平台上不起作用(Windows 10的问题(Flutter for web仍在BETA中。

更多信息请点击此处。

我不确定是否有一种方法可以直接从StatelessWidget测试它,但我可以向您展示一种使用Clean Architecture的一些概念的方法。基本上,您希望将UI(即小部件(与纯逻辑解耦。所以,我通常要做的是有一个处理逻辑的类,比如:

class MyWidgetViewModel {
/// Whether or not the current environment is web.
/// Should only be overridden for testing purposes.
/// Otherwise, defaults to [kIsWeb].
@visibleForTesting
bool isWeb = kIsWeb;
}

在这里,我已经将kIsWeb常量封装在另一个变量isWeb中,该变量默认为kIsWeb。这意味着它可以在以后重新分配,而且,由于注释@visibleForTesting,它只对测试用例可见。

此时,我们可以在小部件中引用该类。我通常将依赖注入与Provider或BLoC一起使用,但在这里,为了简单起见,我只在小部件构造函数中传递ViewModel。

class MyWidget extends StatelessWidget {
final MyWidgetViewModel myViewModel;
const MyWidget(this.myViewModel, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
if (myViewModel.isWeb) { //<- Here we use `isWeb` instead of `kIsWeb`
return Text("I'm web");
} else {
return Text("I'm not web");
}
}
}

最后,我们可以在测试中利用isWeb变量。在设置变量期间,不要忘记将MyWidgetViewModel()的实例传递给MyWidget

test(
'Test based on platform (is web or not).',
() async {
// Arrange (setup)
...
final MyWidgetViewModel myViewModel = MyWidgetViewModel();
myViewModel.isWeb = true; //<- Use this to assign the value you prefer
...

// Assert (expect, verify)
...
},
);

您还可以向小部件添加一个构造函数和属性,用@visibleForTesting进行装饰。类似于:

class MyWidget extends StatelessWidget {
final bool isTestingForWeb;
MyWidget({@visibleForTesting this.isTestingForWeb = false});
@override
Widget build(BuildContext context) {
if (kIsWeb || isTestingForWeb) {
return Text("I'm web");
} else {
return Text("I'm not web");
}
}
}

相关内容

  • 没有找到相关文章

最新更新