gpt4 book ai didi

angular - 在单元测试中使用参数模拟 ngrx 存储选择器(Angular)

转载 作者:行者123 更新时间:2023-12-04 16:29:05 24 4
gpt4 key购买 nike

我正在尝试为 Angular 中的服务编写单元测试。
我想模拟 ngrx 的 store.select 函数,所以我可以测试一个服务如何对商店选择器返回的不同值使用react。我希望能够单独模拟每个选择器。

我的主要问题是如何模拟参数化选择器。

我以前使用过映射到 select 函数的 BehaviourSubject,但这不允许您为不同的选择器返回不同的值。它不可读,因为你模拟的选择器并不明显。

Opt 1: Mock Store using subject:无法知道该主题对应哪个选择器,不能为不同的选择器返回不同的值。

//service.spec.ts

const selectSubject = new BehaviourSubject(null);
class MockStore {
select = () => selectSubject;
}

Opt 2: Mock Store using switch: works for different selectors, but cannot make it work when the selectors have parameters.

//service.spec.ts
    // This works well but how can I make it work with selectors with parameters??
const firstSubject = new BehaviourSubject(null);
const secondSubject = new BehaviourSubject(null);
class MockStore {
select = (selector) => {
switch (selector): {
case FirstSelector: {
return firstSubject;
}
case SecondSelector: {
return secondSubject;
}
}
};
}

describe('TestService', () => {
let service: TestService;
let store: Store<any>;

beforeEach(() => {
TestBed.configureTestingModule({
providers: [
TestService,
{ provide: Store, useClass: MockStore }
],
});

service = TestBed.get(TestService);
store = TestBed.get(Store);
});

it('should do X when first selector returns A and second selector returns B', () => {
firstSelectorSubject.next(A);
secondSelectorSubject.next(B);

// Write expectation
});
});

我想模拟带有参数化选择器的服务方法,因此我可以使用不同的 id 值测试 getUserName
getUserName(id: string): Observable<string> {
return this.store.select(getUser(id)).pipe(
filter(user => user !== null),
map(user => user.fullName)
);
}

最佳答案

NgRx 7.0 包括用于模拟 Store 的 @ngrx/store/testing。有一个非常方便的 overrideSelector 方法。您基本上是在模拟选择器的输出,因此参数无关紧要。

https://medium.com/ngconf/mockstore-in-ngrx-v7-0-f7803708de4e

mockStore.overrideSelector(yourSelector, expectedOutput);

您还可以在 MockStore 的初始化中设置选择器:
const mockStore = new MockStore<fromState.IState>(
new MockState(),
new ActionsSubject(),
null,
null,
[{
selector: yourSelector,
value: expectedOutput
}]
);

如果你想实际测试选择器,你应该有一个专门用于选择器的测试文件。要测试参数化选择器,您将使用投影仪方法。它接受选择器作用的状态(或对象)切片和任何参数。在我的示例中,我正在测试 NgRx 实体。

选择器.ts:
export const getEntityById: any = createSelector(
getEntitiesAsDictionary,
(entities, props) => entities[props.id]
);

规范:
const expectedId = 111;
const expected = { id: expectedId , user: { userId: expectedId } };

const iEntities = {
[expectedId ]: expected,
[222]: { id: 222, user: { userId: 222 }},
[333]: { id: 333, user: { userId:333 }}
};

const actual = fromState.getEntityById.projector(iEntities, { id: expectedId });

expect(actual).toEqual(expected);

关于angular - 在单元测试中使用参数模拟 ngrx 存储选择器(Angular),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55737456/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com