如何在颤动中测试状态?
How to test state in flutter?
所以我有一个简单的计数器应用程序,
class CounterApp extends StatefulWidget {
const CounterApp({Key? key}) : super(key: key);
@override
_CounterAppState createState() => _CounterAppState();
}
class _CounterAppState extends State<CounterApp> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Text(_counter.toString()),
),
);
}
}
那么如何测试 _counter
状态?
我试过这样做,
testWidgets("counter", (tester) async {
const key = Key("counter");
await tester.pumpWidget(const CounterApp(key: key));
final state = tester.state(find.byKey(key));
expect(state._counter, 0);
});
但是我收到错误 Error: The getter '_counter' isn't defined for the class
。我们甚至应该测试状态吗?
首先在使用state
方法时需要指定类型,以免编译出错:
final _CounterAppState state = tester.state(find.byKey(key));
其次,_CounterAppState
和 _counter
是私有的,您不应该直接测试私有 classes/variables。您可以制作 class public 并为私有变量提供 public getter:
int get testCounter => _counter;
但是,有一种访问私有声明的方法我不推荐。用 @visibleForTesting
注释你的私人 variable/class 将使它 public 使代码可测试。不要忘记导入基础库或元库。
visibleForTesting top-level constant
Used to annotate a declaration that was made public, so that it is
more visible than otherwise necessary, to make code testable.
Tools, such as the analyzer, can provide feedback if
- the annotation is associated with a declaration not in the lib folder of a package, or a private declaration, or a declaration in an
unnamed static extension, or
- the declaration is referenced outside of its defining library or a library which is in the test folder of the defining package.
实现如下:
// Import the foundation library
import 'package:flutter/foundation.dart';
class CounterApp extends StatefulWidget {
const CounterApp({Key? key}) : super(key: key);
@override
_CounterAppState createState() => _CounterAppState();
}
// Add the annotation above the class
@visibleForTesting
class _CounterAppState extends State<CounterApp> {
// Add the annotation above the variable
@visibleForTesting
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Text(_counter.toString()),
),
);
}
}
您可能希望在测试后删除注释。
所以我有一个简单的计数器应用程序,
class CounterApp extends StatefulWidget {
const CounterApp({Key? key}) : super(key: key);
@override
_CounterAppState createState() => _CounterAppState();
}
class _CounterAppState extends State<CounterApp> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Text(_counter.toString()),
),
);
}
}
那么如何测试 _counter
状态?
我试过这样做,
testWidgets("counter", (tester) async {
const key = Key("counter");
await tester.pumpWidget(const CounterApp(key: key));
final state = tester.state(find.byKey(key));
expect(state._counter, 0);
});
但是我收到错误 Error: The getter '_counter' isn't defined for the class
。我们甚至应该测试状态吗?
首先在使用state
方法时需要指定类型,以免编译出错:
final _CounterAppState state = tester.state(find.byKey(key));
其次,_CounterAppState
和 _counter
是私有的,您不应该直接测试私有 classes/variables。您可以制作 class public 并为私有变量提供 public getter:
int get testCounter => _counter;
但是,有一种访问私有声明的方法我不推荐。用 @visibleForTesting
注释你的私人 variable/class 将使它 public 使代码可测试。不要忘记导入基础库或元库。
visibleForTesting top-level constant
Used to annotate a declaration that was made public, so that it is more visible than otherwise necessary, to make code testable.
Tools, such as the analyzer, can provide feedback if
- the annotation is associated with a declaration not in the lib folder of a package, or a private declaration, or a declaration in an unnamed static extension, or
- the declaration is referenced outside of its defining library or a library which is in the test folder of the defining package.
实现如下:
// Import the foundation library
import 'package:flutter/foundation.dart';
class CounterApp extends StatefulWidget {
const CounterApp({Key? key}) : super(key: key);
@override
_CounterAppState createState() => _CounterAppState();
}
// Add the annotation above the class
@visibleForTesting
class _CounterAppState extends State<CounterApp> {
// Add the annotation above the variable
@visibleForTesting
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Text(_counter.toString()),
),
);
}
}
您可能希望在测试后删除注释。