首页 > 解决方案 > 使用动作参数 Flutter 测试 Redux-Saga

问题描述

我正在尝试测试参数是动作的传奇,但是我收到以下错误

NoSuchMethodError: Closure call with mismatched arguments: function 'startUp'
Receiver: Closure: ({dynamic action}) => dynamic from Function 'startUp': static.
Tried calling: startUp(Bootstrap)
Found: startUp({dynamic action}) => dynamic

我如何测试这个传奇?下面的测试示例来自flutter redux saga docs,但它根本不广泛

// Action
class Bootstrap {
  final String name;
  Bootstrap (this.name);
}

// Saga
startUp({dynamic action}) sync* {
  // todo api call
  yield Put(Load(action.name));
}


watchSaga() sync* {
  yield TakeLatest(startUp, pattern: Bootstrap);
}


// Test
void main() {
  group('Middleware tests', () {
    test('callApi test', () async {
      var sagaMiddleware = createTestMiddleware();

      var dispatched = [];

      sagaMiddleware.dispatch = (dynamic action) {
        dispatched.add(action);
      };

      sagaMiddleware.getState = () {
        return 'test';
      };

      var task =
          sagaMiddleware.run(startUp, args: [Bootstrap]); // Bootstrap is the action class
      expect(task.toFuture(), completion(equals(0)));
      expect(task.toFuture().then((value) => dispatched),
          completion([TypeMatcher<Load>()]));
    });
  });
}

标签: flutterdartredux-sagaflutter-testflutter-redux

解决方案


您应该首先运行 watchSaga。然后您可以调度操作,它将处理 startUp saga 运行案例。我建议您测试 saga 生成器功能进行测试。

检查以下链接以测试 sagas。

https://github.com/reduxsaga/redux_saga/blob/master/doc/advanced/Testing.md

TakeLatest效果如何使用,可以查看;

https://pub.dev/documentation/redux_saga/latest/redux_saga/TakeLatest.html

测试完整的 saga 可能有点困难。如果是这样,您可能需要创建一个不同的测试基础设施来处理所有问题(测试 redux 存储、模拟函数、效果中间件等)。

对于您的情况,如下所示;

import 'package:redux_saga/redux_saga.dart';
import 'package:test/test.dart';

bool called = false;

void Load(name) async {
  //do something here
  called = true;
}

// Action
class Bootstrap {
  final String name;
  Bootstrap(this.name);
}

// Saga
startUp({dynamic action}) sync* {
  // todo api call
  print('here');
  yield Call(Load, args: [action.name]);
}

watchSaga() sync* {
  yield TakeLatest(startUp, pattern: Bootstrap);
}

void main() {

  group('Middleware tests', () {
    test('callApi test', () async {
      var sagaMiddleware = createTestMiddleware();

      //var dispatched = [];

      // sagaMiddleware.dispatch = (dynamic action) {
      //   print(action);
      //   dispatched.add(action);
      // };

      // sagaMiddleware.getState = () {
      //   return 'test';
      // };

      sagaMiddleware.run(watchSaga);

      called = false;

      var task = sagaMiddleware.run(() sync* {
        yield Put(Bootstrap('load_something'));
      });

      expect(task.toFuture().then((value) => called), completion(equals(true)));
    });
  });
}

请注意,您不应在此处使用虚假方法(dispatch 和 getState)以使 TakeLatest 正常运行。


推荐阅读