单元测试中如何比较两个继承Equatable的Either对象?
解决Either类型单元测试不匹配的问题
问题根源
你碰到的核心问题是:dartz包里的Either/Right本身没实现Equatable接口。哪怕你把内部的CleaningJob和List都搞定了Equatable对比,外层的Either容器还是会用默认的对象引用判断相等性——哪怕内容完全一样,只要是不同实例,就会判定不相等。
具体修复方法
方法1:给Either加Equatable对比扩展
自己写个扩展方法,让Either能按内容对比:
import 'package:dartz/dartz.dart'; import 'package:equatable/equatable.dart'; extension EitherEquatable<L, R> on Either<L, R> { bool equals(Either<L, R> other) { return fold( (left) => other.fold( (otherLeft) => left is Equatable && otherLeft is Equatable ? left == otherLeft : left == otherLeft, (_) => false, ), (right) => other.fold( (_) => false, (otherRight) => right is Equatable && otherRight is Equatable ? right == otherRight : right == otherRight, ), ); } }
测试时改用这个方法:
expect(result.equals(tCleaningJobsModelResponse), isTrue);
方法2:写个自定义测试匹配器
针对Right类型写个专属匹配器,直接对比内部值:
import 'package:dartz/dartz.dart'; import 'package:test/test.dart'; Matcher isRightEqualTo<R>(R value) => _RightMatcher(value); class _RightMatcher extends Matcher { final dynamic expectedValue; _RightMatcher(this.expectedValue); @override bool matches(dynamic item, Map matchState) { return item is Right && item.value == expectedValue; } @override Description describe(Description description) { return description.add('Right($expectedValue)'); } }
测试代码改成:
expect(result, isRightEqualTo(tCleaningJobsModel));
方法3:直接拆解Either对比
绕开容器,直接取出内部值对比:
result.fold( (failure) => fail('预期是Right结果,实际拿到Left'), (jobs) => expect(jobs, tCleaningJobsModel), );
额外要检查的点
- 如果你的测试场景可能出现Left值,记得Failure类也要实现Equatable,不然Left的对比也会出问题
- 确认List的对比逻辑:CleaningJob实现Equatable后,Equatable的List对比会按内容逐一比较,所以只要CleaningJob的==没问题,List的内容对比就不会出错
内容的提问来源于stack exchange,提问作者w461
相关产品推荐
相关产品推荐

