Angular DataSource管道测试失败:空数组返回值匹配问题
解决MatTableDataSource管道测试失败的问题
我明白你遇到的困扰了——明明看起来返回的结果一样,用toEqual直接对比两个MatTableDataSource实例却失败了。这是因为**toEqual会深度遍历对比对象的所有属性,而MatTableDataSource内部包含了RxJS Observable(比如_filter)和多个内置方法(比如sortingDataAccessor),这些元素的引用在两个不同实例里是完全独立的**,哪怕它们的功能逻辑一致,也过不了深度对比这一关。
问题根源
你写的expect(pipe.transform([])).toEqual(new MatTableDataSource([]))里,左右两边是两个完全独立的MatTableDataSource实例:
- 它们的
data属性确实都是空数组,但实例本身的其他内部属性(比如Observable的订阅者、内置方法的引用)都是不一样的 - Jasmine的
toEqual会递归检查这些内部细节,发现函数引用、Observable内部结构不匹配,就会抛出你看到的那些错误
正确的测试方式
我们不需要对比整个实例,只需要验证管道返回的结果满足两个核心要求:
- 它确实是
MatTableDataSource类型的实例 - 它的
data属性和我们传入的数组完全一致
修改后的测试用例如下:
import { TestBed, async, inject } from '@angular/core/testing'; import { DataSourcePipe } from './datasource-pipe.pipe'; import { MatTableDataSource } from '@angular/material'; describe('Pipe: Datasource', () => { let pipe: DataSourcePipe; beforeEach(() => { pipe = new DataSourcePipe(); }); describe('Tests', () => { it('providing an empty array returns a MatTableDataSource with empty data', () => { const result = pipe.transform([]); // 验证返回的是正确的实例类型 expect(result).toBeInstanceOf(MatTableDataSource); // 验证数据源的内容符合预期 expect(result.data).toEqual([]); }); // 可以补充一个非空数组的测试用例,覆盖更多场景 it('providing a non-empty array returns a MatTableDataSource with correct data', () => { const testData = [{id: 1, name: 'Test 1'}, {id: 2, name: 'Test 2'}]; const result = pipe.transform(testData); expect(result.data).toEqual(testData); }); }); });
这样修改后,测试只会聚焦在我们真正关心的逻辑上:管道是否正确创建了MatTableDataSource实例,并且把输入的数组正确赋值给了实例的data属性。那些内部的Observable和方法不需要我们去验证——Angular Material的官方测试已经覆盖了这些底层细节,我们只需要确保自己的管道逻辑正确即可。
内容的提问来源于stack exchange,提问作者cucuru
相关产品推荐
相关产品推荐

