简体   繁体   English

测试在 Isolate 上运行代码的 Dart class

[英]Testing Dart class that runs code on Isolate

I have a Dart class that performs computations on Isolate.我有一个在 Isolate 上执行计算的 Dart class。 Here is my code:这是我的代码:

class Mapper {
  SendPort _isolateSendPort;
  Isolate _isolate;

  Mapper() {
    _asyncInit();
  }

  void _asyncInit() async {
    final receivePort = ReceivePort();
    _isolate = await Isolate.spawn(
      _mappingFunction,
      receivePort.sendPort,
    );
    _isolateSendPort = await receivePort.first;
  }

  static void _mappingFunction(SendPort callerSendPort) {
    final newIsolateReceivePort = ReceivePort();
    callerSendPort.send(newIsolateReceivePort.sendPort);

    newIsolateReceivePort.listen((dynamic message) {
        final crossIsolatesMessage =
          message as CrossIsolatesMessage<Input>;

        // some computations...

        crossIsolatesMessage.sender.send(output);
    });
  }

  Future<Output> map(Input input) async {
    final port = ReceivePort();
    _isolateSendPort.send(CrossIsolatesMessage<Input>(
      sender: port.sendPort,
      message: input,
    ));
    return port.map((event) => event as Output).first;
  }

  void dispose() {
    _isolate?.kill(priority: Isolate.immediate);
    _isolate = null;
  }
}

class CrossIsolatesMessage<T> {
  final SendPort sender;
  final T message;

  CrossIsolatesMessage({
    @required this.sender,
    this.message,
  });
}

This code works well when I run Flutter app.当我运行 Flutter 应用程序时,此代码运行良好。 But unit test for public method Future<Output> map(Input input) throws an error NoSuchMethodError which meens _isolateSendPort is null.但是公共方法Future<Output> map(Input input)的单元测试会引发错误NoSuchMethodError ,这_isolateSendPort是 null。

Here is the unit test code:下面是单元测试代码:

test('Mapper map', () {
  final sut = Mapper();
  final inputDummy = Input('123');
  final resultFuture = sut.map(inputDummy);
  final expectedResult = Output('321');
  expectLater(resultFuture, completion(expectedResult));
});

Here is an error:这是一个错误:

NoSuchMethodError: The method 'send' was called on null.
Receiver: null
Tried calling: send(Instance of 'CrossIsolatesMessage<Input>')
dart:core                                                  Object.noSuchMethod

Why this error occurs in tests?为什么在测试中会出现这个错误? And what is the right way to write tests for this class?为这个 class 编写测试的正确方法是什么?

Problem solved.问题解决了。

Create of _isolate and _isolateSendPort is an async operation. _isolate_isolateSendPort的创建是异步操作。 Thats why _isolateSendPort was null on tests.这就是为什么_isolateSendPort在测试中是 null 的原因。 Call method _asyncInit() from Mapper constructor is wrong way to create an isolate.Mapper构造函数调用方法_asyncInit()是创建隔离的错误方法。

Here is working solution with lazy isolate initialization:这是具有延迟隔离初始化的工作解决方案:

class Mapper {
  SendPort _isolateSendPort;
  Isolate _isolate;

  void _initIsolate() async {
    final receivePort = ReceivePort();
    _isolate = await Isolate.spawn(
      _mappingFunction,
      receivePort.sendPort,
    );
    _isolateSendPort = await receivePort.first;
  }

  ...

  Future<Output> map(Input input) async {
    final port = ReceivePort();
    if (_isolateSendPort == null) {
      await _initIsolate();
    }
    _isolateSendPort.send(CrossIsolatesMessage<Input>(
      sender: port.sendPort,
      message: input,
    ));
    return port.map((event) => event as Output).first;
  }

  ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM