我如何为 Flutter 方法编写一个单元测试,稍后用 future 完成?
How do I write a unit test for a Flutter method that completes later with a future?
我正在为调用异步方法的 Flutter 方法编写单元测试,然后 returns,让异步在何时完成。我的测试失败 "after it had already completed".
这是我的测试:
test('mark as viewed', () {
final a = Asset();
expect(a.viewed, false);
a.markAsViewed();
expect(a.viewed, true);
});
这是它正在测试的方法:
void markAsViewed() {
viewed = true;
Repository.get().saveToStorage();
}
saveToStorage()
方法是一个异步方法,我只是让它在后台执行。
我该如何进行这项工作?测试失败告诉我 Make sure to use [expectAsync] or the [completes] matcher when testing async code.
但我不知道该怎么做。谁能解释一下,或者请给我指出正确的文档?当返回的不是 Future
而只是单独完成时,我找不到有关如何处理这些异步的任何信息。
要明确 - 这个单元测试不是关于测试它是否被保存到存储,只是一个基本的测试设置 viewed
为 true
。
已编辑
错误如下:
package:flutter/src/services/platform_channel.dart 319:7 MethodChannel.invokeMethod
===== asynchronous gap ===========================
dart:async _asyncErrorWrapperHelper
package:exec_pointers/asset_details.dart Repository.saveToStorage
package:exec_pointers/asset_details.dart 64:22 Asset.markAsViewed
test/asset_details_test.dart 57:9 main.<fn>.<fn>
This test failed after it had already completed. Make sure to use [expectAsync]
or the [completes] matcher when testing async code.
此代码与实现问题紧密耦合,这使得对其进行孤立测试变得困难。
应该重构它以遵循更 SOLID 的设计,该设计具有显式依赖关系,可以在隔离测试(单元测试)时替换
例如
class Asset {
Asset({Repository repository}) {
this.repository = repository;
}
final Repository repository;
bool viewed;
void markAsViewed() {
viewed = true;
repository.saveToStorage();
}
//...
}
这种方式在测试 mock/stub 依赖项时可用于避免任何不需要的行为。
// Create a Mock Repository using the Mock class provided by the Mockito package.
// Create new instances of this class in each test.
class MockRepository extends Mock implements Repository {}
main() {
test('mark as viewed', () {
final repo = MockRepository();
// Use Mockito to do nothing when it calls the repository
when(repo.saveToStorage())
.thenAnswer((_) async => { });
final subject = Asset(repo);
expect(subject.viewed, false);
subject.markAsViewed();
expect(subject.viewed, true);
//
verify(repo.saveToStorage());
});
}
现在应该可以执行测试,而不会出现依赖项的意外行为。
引用An introduction to unit testing
参考Mock dependencies using Mockito
参考mockito 4.1.1
我正在为调用异步方法的 Flutter 方法编写单元测试,然后 returns,让异步在何时完成。我的测试失败 "after it had already completed".
这是我的测试:
test('mark as viewed', () {
final a = Asset();
expect(a.viewed, false);
a.markAsViewed();
expect(a.viewed, true);
});
这是它正在测试的方法:
void markAsViewed() {
viewed = true;
Repository.get().saveToStorage();
}
saveToStorage()
方法是一个异步方法,我只是让它在后台执行。
我该如何进行这项工作?测试失败告诉我 Make sure to use [expectAsync] or the [completes] matcher when testing async code.
但我不知道该怎么做。谁能解释一下,或者请给我指出正确的文档?当返回的不是 Future
而只是单独完成时,我找不到有关如何处理这些异步的任何信息。
要明确 - 这个单元测试不是关于测试它是否被保存到存储,只是一个基本的测试设置 viewed
为 true
。
已编辑
错误如下:
package:flutter/src/services/platform_channel.dart 319:7 MethodChannel.invokeMethod
===== asynchronous gap ===========================
dart:async _asyncErrorWrapperHelper
package:exec_pointers/asset_details.dart Repository.saveToStorage
package:exec_pointers/asset_details.dart 64:22 Asset.markAsViewed
test/asset_details_test.dart 57:9 main.<fn>.<fn>
This test failed after it had already completed. Make sure to use [expectAsync]
or the [completes] matcher when testing async code.
此代码与实现问题紧密耦合,这使得对其进行孤立测试变得困难。
应该重构它以遵循更 SOLID 的设计,该设计具有显式依赖关系,可以在隔离测试(单元测试)时替换
例如
class Asset {
Asset({Repository repository}) {
this.repository = repository;
}
final Repository repository;
bool viewed;
void markAsViewed() {
viewed = true;
repository.saveToStorage();
}
//...
}
这种方式在测试 mock/stub 依赖项时可用于避免任何不需要的行为。
// Create a Mock Repository using the Mock class provided by the Mockito package.
// Create new instances of this class in each test.
class MockRepository extends Mock implements Repository {}
main() {
test('mark as viewed', () {
final repo = MockRepository();
// Use Mockito to do nothing when it calls the repository
when(repo.saveToStorage())
.thenAnswer((_) async => { });
final subject = Asset(repo);
expect(subject.viewed, false);
subject.markAsViewed();
expect(subject.viewed, true);
//
verify(repo.saveToStorage());
});
}
现在应该可以执行测试,而不会出现依赖项的意外行为。
引用An introduction to unit testing
参考Mock dependencies using Mockito
参考mockito 4.1.1