如何从颤振包"async_redux"模拟 ReduxAction 中的调度方法



我正在Flutter中开发一个android/ios应用程序,我选择使用redux进行状态管理。

我正在为我的 redux 操作编写单元测试,这些操作已使用 async_redux 包实现。

我遵循软件包作者为测试制定的出色指南,但我不确定如何模拟我被测试的操作中进一步操作的调度。

例如,以下LogoutAction调度一个DeleteDatabaseAction并等待它完成:

class LogoutAction extends ReduxAction<AppState> {
@override
Future<AppState> reduce() async {
await dispatchFuture(DeleteDatabaseAction());
return AppState.initialState();
}
}
class DeleteDatabaseAction extends ReduxAction<AppState> {
@override
FutureOr<AppState> reduce() {
throw StateError(
'Unwanted call to runtime implementation of DeleteDatabaseAction',
);
}
}
void main() {
final store = Store<AppState>(initialState: AppState(loggedIn: true));
final storeTester = StoreTester.from(store);
test('Logout action should return correct state and not throw StateError', () async {
storeTester.dispatch(LogoutAction());
TestInfo<AppState> info = await storeTester.wait(LogoutAction);
expect(info.state.loggedIn, false);
});
}

我只想测试正在测试的操作,并存根所有进一步的操作调用。

即如何在ReduxAction上模拟/存根dispatchdispatchFuture方法,以便运行时DeleteDatabaseAction实现不运行?

到目前为止,我已经尝试了:

  • 使用get_it注入DeleteDatabaseAction并在测试期间注入模拟

    • 我有 100+ 个操作现在需要添加到我的上下文中
    • 某些操作的参数会根据调用它们的位置而变化,因此无法在应用启动时注册
  • 子类Store,覆盖上述方法并在我的测试中使用子类 此处final store = Store<AppState>(initialState: AppState(loggedIn: true))

    • 我将无法调度我的测试操作,因为它在async_redux测试实现中使用相同的存储
    • 在这里:storeTester.dispatch(LogoutAction());
  • 创建一个单独的Dispatcher实现,注入此并在测试期间用模拟覆盖
    • 这将起作用,但这是新的框架,我可以走这条路,但现在我偏离了 asyn_redux 提供的有据可查的框架

当您提出此问题时,这不可用。但现在答案就在这里:https://pub.dev/packages/async_redux#mocking-actions-and-reducers

要模拟操作及其化简器,请首先在测试中创建MockStore,而不是常规StoreMockStore有一个mocks参数,它是一个映射,其中键是操作类型,值是模拟。例如:

var store = MockStore<AppState>(
initialState: initialState,  
mocks: {
MyAction1 : ...
MyAction2 : ...
...
},
);

但是,还有其他方法:

  1. 正如您所说,使用get_it或其他一些依赖项注入代码将 http 客户端注入到动作缩减器中。这很好用。

  2. 使用DAO。例如:

    class DeleteDatabaseAction extends ReduxAction<AppState> {
    @override
    Future<AppState> reduce() {
    await dao.deleteDatabase();
    return null;
    } 
    

    然后你可以模拟 DAO 本身,或者通过get_it注入 DAO。你也可以让道成为某种BaseAction(延伸ReduxAction(的吸气剂,并将其注入到那里。

最新更新