flutter - 使用动作参数 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>()]));
});
});
}
解决方案
您应该首先运行 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 正常运行。