如何使用Jasmine对Facade中的getItem方法进行单元测试
如何正确测试NgRx Facade中的getItem方法
原Facade方法
getItem(number: string): Observable<MyItem> { return this.myStore.pipe(select(myQuery.getItem(number))); }
你现有测试的问题
你写的测试逻辑存在明显问题:
- 监听
store.pipe没有实际意义,我们不需要验证store的pipe方法是否被调用,而是要验证Facade返回的数据是否正确、是否正确使用了对应的选择器。 expect(store).toEqual(getItemsStub())完全不符合测试目标,store对象本身和你的数据stub不可能相等,应该验证的是getItem返回的Observable数据。
正确的测试方式
1. 配置TestBed,使用MockStore
首先在测试文件中用NgRx提供的provideMockStore初始化模拟状态,避免依赖真实的Store:
import { TestBed } from '@angular/core/testing'; import { provideMockStore, MockStore } from '@ngrx/store/testing'; import { MyFacade } from './my.facade'; import { myQuery } from './my.selectors'; import { MyItem } from './my.model'; describe('MyFacade', () => { let facade: MyFacade; let store: MockStore; // 定义初始状态,包含测试需要的Item数据 const initialState = { myFeature: { items: { '1': { id: '1', name: 'Test Item' } as MyItem } } }; beforeEach(() => { TestBed.configureTestingModule({ providers: [ MyFacade, provideMockStore({ initialState }) ] }); facade = TestBed.inject(MyFacade); store = TestBed.inject(MockStore); });
2. 测试getItem返回正确的数据
因为返回的是Observable,需要用异步测试的方式验证数据:
it('getItem should return the correct MyItem for a valid number', (done) => { facade.getItem('1').subscribe(item => { expect(item).toEqual({ id: '1', name: 'Test Item' } as MyItem); done(); // 告知Jasmine异步测试完成 }); });
3. 验证getItem正确调用了选择器
如果需要验证Facade是否正确使用了myQuery.getItem选择器,可以添加这个测试:
it('getItem should invoke the correct selector with the provided number', () => { const selectorSpy = spyOn(myQuery, 'getItem').and.callThrough(); facade.getItem('1'); expect(selectorSpy).toHaveBeenCalledWith('1'); }); });
内容的提问来源于stack exchange,提问作者Cay Dan
相关产品推荐
相关产品推荐

