【发布时间】:2022-01-13 05:07:10
【问题描述】:
我确实坚持在返回值之前进行一些转换的测试流。我使用 Firestore 作为我的数据存储,并有一个单独的数据层执行从 DocumentSnapshot<T> 到我的模型的一些映射。这是一个 repo 的例子:
class RequestsRepository {
final CollectionReference<Request> _requestsCollection =
getIt<FirebaseFirestore>().collection('requests').withConverter<Request>(
fromFirestore: (snapshot, _) => Request.fromJson(snapshot.data()!),
toFirestore: (request, _) => request.toJson());
Stream<Request?> observe(String id) {
return _requestsCollection
.doc(id)
.snapshots()
.map((snapshot) => snapshot.exists ? snapshot.data() : null);
});
}
}
现在我想用测试来介绍observe(id) 函数。这是我找到的解决方案,下面我将解释原因:
test('request exists', () async {
// WHEN
final stream = repository.observe(request.id);
// expected events
final events = [null, request, request..completed = true, null];
var eventIndex = 0;
// THEN
stream.listen(expectAsync1((value) async {
await Future.delayed(Duration(milliseconds: 100));
expect(value, events[eventIndex]);
eventIndex++;
}, max: -1));
// GIVEN
await firestore
.collection('requests')
.doc(request.id)
.set(request.toJson());
request.completed = true;
await firestore
.collection('requests')
.doc(request.id)
.set(request.toJson());
// reset request data
request.completed = false;
});
我尝试了emitsInOrder 流匹配器,但它失败了,因为我在observe(id) 函数内部进行映射,结果实际上不是request 对象而是_MapStream<DocumentSnapshot<Request?>, Request?>,而是因为流映射函数遵循的逻辑:
Stream<S> map<S>(S convert(T event)) {
return new _MapStream<T, S>(this, convert);
}
我来的解决方案确实适用于这个案例,但它不适用于其他测试,而且解决方案很臭。有什么建议如何测试这些流?
更新:
@pskink 的每条评论是演示测试失败,原因相同:
class Test {
Stream<B> observe() {
return Stream.periodic(Duration(milliseconds: 500), (i) => A(i * 10))
.map((i) => B('s${i.a}'));
}
}
class A {
final int a;
A(this.a);
bool operator ==(o) => o is A && a == o.a;
int get hashCode => a.hashCode;
}
class B {
final String b;
B(this.b);
bool operator ==(o) => o is B && b == o.b;
int get hashCode => b.hashCode;
}
void main() {
test('mapped stream: A > B', () async {
final stream = Test().observe();
expect(stream, emitsInOrder([B('s0'), B('s10'), B('s20'), B('s30')]));
});
}
到目前为止,它通过了测试。
【问题讨论】:
-
发布一个可以轻松复制的短代码 sn-p(没有任何 Firestore 部门),例如:
test('mapped stream: int > String', () async { final stream = Stream.periodic(Duration(milliseconds: 500), (i) => i * 10) .take(4) .map((i) => 's$i'); expect(stream, emitsInOrder(['s0', 's10', 's20', 's30'])); });- 这里Stream<int>是Stream.map()ed 到Stream<String>和测试通过了 -
@pskink 是的,对不起,我的错误。所以我更新了测试以接近我所看到的,并且看起来短代码 sn-p 工作正常。
标签: flutter testing flutter-test