【问题标题】:Unit testing Dart async stream单元测试 Dart 异步流
【发布时间】:2018-08-10 00:29:41
【问题描述】:

我正在尝试在 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);

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

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

【问题讨论】:

  • 尼特:不要在这一行分配list PathComponentList list = PathComponentList(); - 让它为空!
  • 是的,我最终会看到的。代码开始时没有 setup() 方法;我重构时忘记解决这个问题。谢谢!

标签: unit-testing async-await dart


【解决方案1】:

问题:在您注册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));
});

【讨论】:

  • 谢谢。应该是显而易见的。我也没有看到 Stream 的 take(count) 方法。这正是我想要的。
  • 很好,但我应该如何测试流的初始值?例如,如果我使用 boolean: true 初始化流。没有找到办法,因为当我写期望时,流已经被填充了
猜你喜欢
  • 1970-01-01
  • 2012-07-15
  • 1970-01-01
  • 2020-07-14
  • 2012-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多