gpt4 book ai didi

angular - 单元测试复杂的 Observable 流程

转载 作者:太空狗 更新时间:2023-10-29 17:54:31 28 4
gpt4 key购买 nike

我有以下函数,它(我认为)返回一个复合可观察对象:

test(cell) {
const observ1 = this.store.select('range').flatMap((val: IRange) => {return this.getCellOEE(val.value)});
const observ2 = this.getCellOEE(cell);
return Observable.merge(observ1, observ2);
}

我在 angular 4 服务中使用它,并尝试使用 jasmine 和 karma 进行单元测试。

所以我是这样 mock 商店的:

class mockStore {
select(): Observable<IRange> {
return Observable.of({value: 'daily', start: moment(), end: moment()}, {value: 'monthly', start: moment(), end: moment()})
}
}

然后我有以下测试:

 it('should update result on store change', fakeAsync(inject(
[MockBackend, OeeService],
(backend: MockBackend, s: OeeService) => {
const urls = [];

backend.connections.subscribe((connection: MockConnection) => {
const req: any = connection.request;
urls.push(req.url);
if (req.method === RequestMethod.Get && req.url === 'api/getLine/data' req.headers.get('range') === 'daily') {
connection.mockRespond(new Response(new ResponseOptions({ body: { data: 12 } })));
}
if (req.method === RequestMethod.Get && req.url === 'api/getLine/data' &&
req.headers.get('range') === 'monthly') {
connection.mockRespond(new Response(new ResponseOptions({ body: { data: 15 } })));
}
});
let value;
s.test('powders').subscribe(val => {
value = val;
})

tick();
expect(value).toEqual(12);
tick();
expect(value).toEqual(15);
})
));

我希望很清楚我要实现的目标,所以当最初调用 test() 函数时,会进行直接的 http 调用,但随后我的模拟商店应该发布更改在参数中,将其映射到具有新参数的 http 请求,然后返回不同的值。

我目前得到第一个 expect() 通过,但第二个失败:

Expected 12 to contain 15

所以我认为存在时间问题?有什么想法可以解决这个问题吗?我认为测试对于验证很重要,因为这样我就可以起诉一些优秀的旧 TDD 来证明这种方法是否有效。

更新:

这是我的完整单元测试 file

最佳答案

您是对的,测试存在时间问题。当第一个 Expect() 表达式出现时,两个模拟 Responses 都已返回。要修复您的测试,您可以更改其中一个响应以使用 setTimeout() 并将 expect 子句之间的 tick() 设置为该延迟后的某个时间。

例如:

if (req.method === RequestMethod.Get && req.url === 'api/getLine/data' && req.headers.get('range') === 'monthly') {
setTimeout(() => {
connection.mockRespond(new Response(new ResponseOptions({ body: { data: 15 } }))); }, 100);
}

和:

expect(value).toEqual(12);
tick(100);
expect(value).toEqual(15);

但是,与 julia 上面所说的类似,更好的测试是将值插入数组并检查各个索引处的值是否正确。在这种情况下,我建议将测试函数中的 flatMap() 替换为 concatMap(),这样可以保留顺序。然后,您可以编写多个测试,每个响应都延迟,并仍然检查各个索引处的值是否正确:

tick(100);
expect(values[0]).toEqual(12);
expect(values[1]).toEqual(15);

关于angular - 单元测试复杂的 Observable 流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43766574/

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