Javascript 测试一个角度可观察物是否发出一个值或序列

Javascript 测试一个角度可观察物是否发出一个值或序列,javascript,angular,jasmine,rxjs,observable,Javascript,Angular,Jasmine,Rxjs,Observable,我有一个服务,它可以创建一个可观察的值,并且可以相对容易地测试所发出的值是否符合预期 例如: describe('service', () => { beforeEach(() => { TestBed.configureTestingModule({providers: [MyService]}); }); it('should emit true', async(() => { const service = Tes

我有一个服务,它可以创建一个可观察的值,并且可以相对容易地测试所发出的值是否符合预期

例如:

describe('service', () => {
    beforeEach(() => {
        TestBed.configureTestingModule({providers: [MyService]});
    });

    it('should emit true', async(() => {
        const service = TestBed.get(MyService);
        service.values$.subscribe((value) => expect(value).toBeTruthy());
    }));
});
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);
    }));
});
上面的方法用于测试预期值,但它仅在服务实际发出值时才起作用。如果您遇到服务无法发出值的边缘情况,那么测试本身实际上通过了,Jasmine会记录警告消息“SPEC HAS NO EXPECTATIONS 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', () => {
    beforeEach(() => {
        TestBed.configureTestingModule({providers: [MyService]});
    });

    it('should emit true', async(() => {
        const service = TestBed.get(MyService);
        service.values$.subscribe((value) => expect(value).toBeTruthy());
    }));
});
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);
    }));
});
description('service',()=>{
让完成:主题;
在每个之前(()=>{
configureTestingModule({providers:[MyService]});
完成=新主题();
});
之后(()=>{
完成。下一步();
完成的;完成的;
});
它('should emit true',异步(()=>{
const service=TestBed.get(MyService);
让价值;
服务变更$
.烟斗(
直到(完成),
finalize(()=>expect(value).toBeTruthy())
)
.认购((v)=>value=v);
}));
});
在上面的示例中,该值存储在一个局部变量中,然后在可观察对象完成时检查预期结果。我使用
afterEach()
takeUntil()
强制完成

问题:


我的方法是否有任何副作用,如果有,执行此类测试的更具角度/茉莉花风格的方法是什么。我担心您不应该在afterEach()生命周期调用期间执行expect断言。

这对我来说似乎有些过分

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

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

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

Overkill是我的中间名。谢谢,我试试看。我读过的所有地方都说应该使用Angular async函数。这有什么不同呢?对于初学者来说,这是有偏见的,因为在测试中你没有被迫使用测试床或任何角度特性。例如,我们有很重的组件,我们对代码进行单元测试,但是使用E2E测试接口(大大减少了测试时间)。Angular
async
(它不是
fakeAsync
BTW吗?)简单地解决了代码中挂起的操作,它没有做更多的事情。我从未使用过它,也从未遇到过异步代码挂起的测试问题。所以它确实是基于观点的,但对我来说,
async
是无用的!脸掌。我刚刚读取了
it()
的函数签名,它支持设置超时值。我的印象是Jasmine完全是同步的。发生了这种情况,至少你知道,你的测试输入的代码要少得多:)