测试Angular observable是否发出值或序列



我有一个服务,它创建了一个可观察的、发出值的服务,而且测试发出的值是否如预期的那样相对容易。

例如:

describe('service', () => {
beforeEach(() => {
TestBed.configureTestingModule({providers: [MyService]});
});
it('should emit true', async(() => {
const service = TestBed.get(MyService);
service.values$.subscribe((value) => expect(value).toBeTruthy());
}));
});

上面的方法可以测试预期值,但只有当服务实际发出值时,它才有效。如果您遇到服务无法发出值的边缘情况,那么测试本身实际上通过了,Jasmine会记录警告消息"SPEC HAS NO EXPECTIONS should be created"。

我在谷歌上搜索了一段时间,试图找出如何将这种情况视为错误,并想出了这种方法。

it('should emit true', async(() => {
const service = TestBed.get(MyService);
let value;
service.values$.subscribe((v) => value = v);
expect(value).toBeTruthy();
}));

以上内容仅适用于同步可观察性,对我来说就像代码的气味。另一位开发人员会看到这一点,并认为这是一个糟糕的质量测试。

经过几天的思考。我想用takeUntil()来强制完成可观测,然后测试预期结果。

例如:

describe('service', () => {
let finished: Subject<void>;
beforeEach(() => {
TestBed.configureTestingModule({providers: [MyService]});
finished = new Subject();
});
afterEach(() => {
finished.next();
finished.complete();
});
it('should emit true', async(() => {
const service = TestBed.get(MyService);
let value;
service.changes$
.pipe(
takeUntil(finished),
finalize(() => expect(value).toBeTruthy())
)
.subscribe((v) => value = v);
}));
});

在上面的例子中,值被存储在一个局部变量中,然后在可观察到的结果完成时检查预期结果。我通过使用afterEach()takeUntil()来强制完成。

问题:

我的方法有任何副作用吗?如果有,执行这些测试的更具角度/Jasmine的方式会是什么。我担心您不应该在afterEach((生命周期调用期间执行expect断言。

这对我来说似乎有些过头了。

Jasmine在测试中提供了回调,你可以简单地使用它吗?

it('should X', doneCallback => {
myObs.subscribe(res => {
expect(x).toBe(y);
doneCallback();
});
});

如果没有调用回调,测试将失败,并出现超时异常(这意味着在这个失败的测试之后将不再运行任何测试(

最新更新