Dart-如何模拟返回未来的方法

Dart-如何模拟返回未来的方法,dart,dart-async,dart-unittest,Dart,Dart Async,Dart Unittest,我有一个类,它定义了一个返回未来的方法。Future包含也返回Future的类的列表 类用户{ 未来专辑(){ }; } 班级相册{ 未来照片(){ } }; 在测试另一个类时,在这些类中模拟方法的最佳方法是什么 我尝试测试的类看起来有点像 课堂演示者{ 演示者(用户){ user.albums()。然后(\u processAlbums); } _processAlbums(列出相册){ albums.forEach((album)=>album.photos.then(_processPh

我有一个类,它定义了一个返回未来的方法。Future包含也返回Future的类的列表

类用户{
未来专辑(){
};
}
班级相册{
未来照片(){
}
};
在测试另一个类时,在这些类中模拟方法的最佳方法是什么

我尝试测试的类看起来有点像

课堂演示者{
演示者(用户){
user.albums()。然后(\u processAlbums);
}
_processAlbums(列出相册){
albums.forEach((album)=>album.photos.then(_processPhotos));
}
_处理照片(列出照片){
东西
}
}
我试着写一个这样的单元测试

类MockUser扩展Mock实现用户{}
类MockAlbum扩展Mock实现相册{}
类MockPhoto扩展Mock实现Photo{}
类MockFutureList扩展了Mock实现Future{
模拟未来列表(列表项){
when(callsTo(“then”))。然后返回(项目);
}
}
void main(){
test(“constructor应该向用户请求相册”,(){
MockUser=新MockUser();
MockAlbum album=新建MockAlbum();
唱片列表=[album];
MockPhoto photo=新的MockPhoto();
照片列表=[album];
user.when(callsTo(“albums”))。然后return(newmockfuturelist(listOfAlbums));
相册。当(调用(“照片”))。然后返回(新模拟未来列表(照片列表));
PicasaPhotoPresentor underTest=新的PicasaPhotoPresentor(视图,用户);
user.getLogs(callsTo(“相册”)).verify(happenedOnce);
相册。获取日志(调用(“照片”))。验证(偶然事件);
});
}
这允许我测试构造函数是否调用了user.photos()方法,但没有测试是否调用了album.photos()方法

我不确定模仿未来是一个好主意——创造一个包含模仿列表的“真实”未来不是更好吗


任何想法都会非常有用

由于您只对验证调用了
User
Album
中的方法感兴趣,因此不需要模拟
未来的

验证模拟在这里变得有点棘手,因为您正在构造函数中链接未来。稍微了解一下Dart中的工作原理,我建议在创建演示者后使用future并调用
expectAsync

expectAsync
函数告诉单元测试库等待,直到调用它来验证测试。否则,测试将在不运行预期的情况下成功完成

这样,您的测试应该是这样的:

import'包:unittest/unittest.dart';
类MockUser扩展Mock实现用户{}
类MockAlbum扩展Mock实现相册{}
void main(){
test(“constructor应该向用户请求相册”,(){
var user=new MockUser();
var album=new MockAlbum();
user.when(callsTo(“albums”))。然后return(newfuture(()=>[album]);
var presenter=新的PicasaPhotoPresentor(视图,用户);
//在下一个事件循环中验证模拟。
新未来(expectAsync(){
相册。获取日志(调用(“照片”))。验证(偶然性);
}));
});
}

以下是我如何做到这一点的

1) 定义FutureCallbackMock

class FutureCallbackMock extends Mock implements Function {
  Future<void> call();
}
4) 如果需要,填写未来:

completer.complete();
注意:在颤振测试中,我必须像这样在
tester.runAsync
中包装我的测试

      testWidgets(
          'when tapped disables underlying button until future completes',
          (WidgetTester tester) async {
        await tester.runAsync(() async {
           // test here
        });
      });


我对我的代码进行了测试,发现使用thenReturn时出现了一个错误thenReturn'不应用于返回未来。相反,在将其更改为thenAnswer后使用“thenAnswer(()=>future)”即可。
completer.complete();
      testWidgets(
          'when tapped disables underlying button until future completes',
          (WidgetTester tester) async {
        await tester.runAsync(() async {
           // test here
        });
      });