我正在关注Reso Coder的video关于Flutter / Dart中的单元测试。在视频中,他正在测试一个对远程服务进行异步调用的类(使用Mockito进行模拟):
正在测试的类(不是完整代码):
Class ServiceChangeNotifier extends ChangeNotifier {
final Service _service;
ServiceChangeNotifier(Service this._service);
bool _isLoading = false;
bool get isLoading => _isLoading;
List<int> _res = [];
List<int> get res => _res;
Future<void> doService() async {
_isLoading = true;
notifyListeners();
_res = await _service.runService();
_isLoading = false;
notifyListeners();
}
请注意,他在服务调用之前将_isLoading
更改为true,然后在服务调用之后更改为false。
现在,在测试中,他希望验证加载状态在服务调用之前正确地更新为true,然后在服务调用之后更新为false。为此,他将对异步服务方法的调用设置为Future变量,然后Asserttrue更改,然后等待Future变量,然后Assertfalse:
公寓测试代码
final ServiceChangeNotifier sut = ServiceChangeNotifier(serviceMockup);
test('....',
() async {
// test setup...
final future = sut.doService() // 1
expect(sut.isLoading, true); // 2
await future; // 3
expect(sut.isLoading, false); // 4
// ...
}
我理解为什么你可以在测试true之前等待方法,因为在expect(true)运行之前,它会变成false。我不理解的是检查true(上面的第2行)是如何工作的。是第1行(未来赋值)的逻辑触发了doService方法的执行,还是第3行的等待?
我怀疑我遗漏了一些关于Future/await如何工作和/或expect()如何在测试库中工作的基本信息。This question与这个问题有些关系,但这里我 * 不是 * 询问doSerivce方法的异步部分,而是询问如何根据异步调用来评估_isLoading的同步赋值。
1条答案
按热度按时间uqjltbpv1#
当执行异步函数时,尽可能多的函数是同步执行的;也就是说,它的函数体一直执行到
await
(这是返回Future
并注册适当的完成回调的语法糖)。因此,鉴于:
sut.doService()
被立即调用。doService
的主体立即设置_isLoading = true
,调用notfifyListeners()
[sic],调用_service.runService()
,然后返回Future
。sut.isLoading
在这一点上是true
。1.步骤1返回的
Future
是await
ed,因此执行返回到事件循环。来自_service.runService()
的Future
最终完成,它执行doService()
主体的其余部分,设置_isLoading = false
并再次调用notfifyListeners()
。1.在这一点上的
sut.isLoading
是false
。