Flutter 如何模拟对 rootBundle.loadString(...) 的调用,然后重置模拟的行为?
Posted
技术标签:
【中文标题】Flutter 如何模拟对 rootBundle.loadString(...) 的调用,然后重置模拟的行为?【英文标题】:Flutter how to mock a call to rootBundle.loadString(...), then reset the mocked behavior? 【发布时间】:2020-05-21 14:16:37 【问题描述】:在我的颤振代码中,我有这样做的逻辑:
final jsonString = await rootBundle.loadString('AssetManifest.json');
我有一些测试,我想在到达这条线时返回一个假的AssetManifest.json
。
为了模拟它,我在测试中这样做:
ServicesBinding.instance.defaultBinaryMessenger
.setMockMessageHandler('flutter/assets', (message)
final Uint8List encoded =
utf8.encoder.convert('"Foo.ttf":["Foo.ttf"]');
return Future.value(encoded.buffer.asByteData());
);
奇怪的是,这个工作,但是在它之后运行的任何测试都会挂起(当它到达await rootBundle.loadString('AssetManifest.json')
行时,它们都会卡在代码中。
我已经尝试添加
ServicesBinding.instance.defaultBinaryMessenger
.setMockMessageHandler('flutter/assets', null);
但这似乎并没有正确地“清理”被嘲笑的行为。事实上,如果我在 setUp
中运行上述行,运行的 first 测试会挂起。
所以我是在嘲笑这种行为错了吗?还是我没有正确清理它?
【问题讨论】:
当您说在它之后运行的测试挂起时,您是指同一组中的其他测试、同一文件中的其他测试还是其他文件中的其他测试?我注意到虽然同一组或文件中的测试共享某种程度的状态,但将测试放在单独的文件中会完全从状态的角度隔离它们。我知道这是一种解决方法而不是解决方案,但也许它可以帮助你。 同一文件中的其他测试!有问题的测试之后的任何测试都会挂起。最后,我选择按照您的建议进行操作,将测试放在自己的文件中。 【参考方案1】:我遇到了同样的问题,并认为这是由于捆绑包缓存造成的。这将导致上述测试失败,因为消息永远不会被发送。调用loadString时,可以指定是否缓存结果。例如。 loadString('AssetManifest.json', false)
.
请注意,如果您使用loadStructuredData
,实现可以缓存结果并且您不能告诉它不缓存。
【讨论】:
以上是关于Flutter 如何模拟对 rootBundle.loadString(...) 的调用,然后重置模拟的行为?的主要内容,如果未能解决你的问题,请参考以下文章
从main()调用await rootBundle.loadString(…)时,Flutter应用程序挂起
为啥我在 Flutter 测试期间使用 rootBundle.load 得到“对空值使用空检查运算符”?