单元测试Dart异步流

时间:2018-08-09 15:41:26

标签: unit-testing async-await dart

我试图在Dart中创建一个列表,该列表在每次添加或删除对象时都会发送事件,而我在弄清楚如何为其编写单元测试时遇到了麻烦。

这是列表的代码:

enum Action { Insert, Modify, Remove }

class ListChangeEvent {
  final int index;
  final Action action;
  final PathComponent component;

  ListChangeEvent(this.index, this.action, this.component);
}

class PathComponentList extends DelegatingList<PathComponent> {
  final List<PathComponent> _list = [];

  @override
  List<PathComponent> get delegate => _list;

  var changeController = new StreamController<ListChangeEvent>();
  Stream<ListChangeEvent> get onChange => changeController.stream;

  @override
  void add(PathComponent value) {
    super.add(value);
    changeController
        .add(new ListChangeEvent(this.indexOf(value), Action.Insert, value));
  }
}

现在我想做的是创建一个单元测试,以验证每次插入元素时,我都会在流中传递一个ListChangeEvent。

这是我目前的尝试。我敢肯定,这将永远挂起,因为我从不关闭流。

void main() {
  group('PathComponentList', () {
    PathComponentList list = PathComponentList();
    var body = PathComponent(Path.Body);
    var chance = PathComponent(Path.Chance);
    var crossroads = PathComponent(Path.Crossroads);

    setUp(() async {
      list = PathComponentList();
    });

    test('should fire event when adding', () async {
      list.add(body);
      list.add(chance);
      list.add(crossroads);

      List<ListChangeEvent> events = await list.onChange.toList();
      expect(events[0].action, equals(Action.Insert));
      expect(events[0].index, equals(0));
      expect(events[0].component, equals(body));
    });
  });
}

我试图像这样从流中获取单个元素:

await list.onChange.elementAt(index);

但是,如果我不止一次这样做,则代码会抱怨我已经收听了流。

由于我希望流在应用程序的生命周期内发送ListChangeEvent,所以什么是读取在单元测试中写入此流的三个ListChangeEvent的最佳方法?

1 个答案:

答案 0 :(得分:2)

问题:在您注册onChange侦听器时,事件已经“消失”。

尝试一下:(由于我没有您的PathComponent类型,所以进行了修改)

test('should fire event when adding', () async {
  // Queue up the adds to happen after we listen for the change event
  Timer.run(() {
    list.add(body);
    list.add(chance);
    list.add(crossroads);
  });

  var events = await list.onChange.take(3).toList();

  expect(events[0].action, equals(Action.Insert));
  expect(events[0].index, equals(0));
  expect(events[0].component, equals(body));
});