Nic*_*las 28 unit-testing dart flutter
我在 Dart 类中有一个方法,它接受BuildContext参数,如下所示:
class MyClass {
<return_type> myMethodName(BuildContext context, ...) {
...
doSomething
return something;
}
}
Run Code Online (Sandbox Code Playgroud)
我想测试该方法是否按预期工作:
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
...
void main() {
MyClass sut;
setUp(() {
sut = MyClass();
});
test('me testing', () {
var actual = sut.myMethodName(...);
expect(actual, something);
});
}
Run Code Online (Sandbox Code Playgroud)
当然不行,因为方法myMethodName需要参数BuildContext类型。该值在整个应用程序本身中都可用,但不确定在我的单元测试中从何处获取该值。
jam*_*lin 34
一种方法是testWidgets与Builder小部件结合使用:
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();
},
),
);
});
Run Code Online (Sandbox Code Playgroud)
sur*_*rga 17
您实际上可以模拟 ,BuildContext因此测试将无头运行。我认为它更好,但可能不是您正在寻找的解决方案。
BuildContext是一个抽象类,因此它不能被实例化。任何抽象类都可以通过创建该类的实现来模拟。如果我以你的例子为例,那么代码将如下所示:
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);
});
}
Run Code Online (Sandbox Code Playgroud)
这是在测试用例中检索 BuildContext 实例的一种简单方法:
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.
});
Run Code Online (Sandbox Code Playgroud)
这是受到函数Flutter 测试用例中的Simple dialog control test 的启发showDialog()。
整个“应用程序”由Container一个MaterialApp框架中的小部件组成。该BuildContext实例通过查找检索形式Element相关的实例Container。
我完全同意“surga”的答案,但在某些情况下,它还不够好。就像当你想使用它时,BuildContext例如InhiretedWidget:Provider或MediaQuery。
所以我建议使用默认生成器为您Mockito生成类。BuildContext
@GenerateMocks([BuildContext])
BuildContext _createContext(){
final context = MockBuildContext();
...
Run Code Online (Sandbox Code Playgroud)
并添加build_runner到您的pubspec.yaml
dev_dependencies:
flutter_test:
sdk: flutter
build_runner: any //use any version you want
Run Code Online (Sandbox Code Playgroud)
然后运行这个命令:
flutter packages pub run build_runner build
context现在您可以从该类创建一个对象MockBuildContext,就像通常从MaterialApp.
@GenerateMocks([BuildContext])
BuildContext _createContext(){
final context = MockBuildContext();
final mediaQuery = MediaQuery(
data: MediaQueryData(),
child: const SizedBox(),
);
when(context.widget).thenReturn(const SizedBox());
when(context.findAncestorWidgetOfExactType()).thenReturn(mediaQuery);
when(context.dependOnInheritedWidgetOfExactType<MediaQuery>())
.thenReturn(mediaQuery);
when(context.getElementForInheritedWidgetOfExactType())
.thenReturn(InheritedElement(mediaQuery));
return context;
}
Run Code Online (Sandbox Code Playgroud)
注意:这个Mock不需要添加when..thenReturn,这取决于您的需要。
| 归档时间: |
|
| 查看次数: |
8884 次 |
| 最近记录: |