【问题标题】:angular tests passing before async call has completed?在异步调用完成之前通过角度测试?
【发布时间】:2017-09-18 09:35:07
【问题描述】:

我有以下 Angular (4) 测试,它应该测试服务,但是,它似乎在 Observable 返回和expect get 命中之前通过了。

   it('should enter the assertion', inject(
        [ MockBackend, CellService ],
        ( backend: MockBackend, s: CellService ) => {
            const urls = [];

            backend.connections.subscribe((connection: MockConnection) => {
                const req = connection.request;
                urls.push(req.url);
                if (req.method === RequestMethod.Get && req.url === '/api/getTest') {
                    connection.mockRespond(new Response(new ResponseOptions('enter mocked content')));
                }
            });
            s.getCell('powders').subscribe(val => expect(true).toBeFalsy())
        })
    );

我尝试添加 async/await,但这并没有什么不同。我该怎么做?

更新:

这段代码也通过了...

it('should enter the assertion', async(inject(
    [ MockBackend, CellService ],
    ( backend: MockBackend, s: CellService ) => {
        const urls = [];

        backend.connections.subscribe((connection: MockConnection) => {
            const req = connection.request;
            urls.push(req.url);
            if (req.method === RequestMethod.Get && req.url === '/api/getTest') {
                connection.mockRespond(new Response(new ResponseOptions('enter mocked content')));
            }
        });
        s.getCell('powders').subscribe(val => expect(true).toBeFalsy())
    })
));

【问题讨论】:

    标签: angular typescript jasmine


    【解决方案1】:

    在 Angular 的 async 中封装测试

    import { async } from '@angular/core/testing';
    
                             ---==== vvvv ===----
    it('should enter the assertion', async(inject(
        [ MockBackend, CellService ],
        ( backend: MockBackend, s: CellService ) => {
            ...
        })
    ));
    

    这会将测试包装在测试区域中,这将允许 Angular 在完成测试之前实际等待所有异步任务完成。

    另请参阅:

    更新

    试试fakeAsycn/tick

    import { fakeAsync } from '@angular/core/testing';
    
    it('should enter the assertion', fakeAsync(inject(
        [ MockBackend, CellService ],
        ( backend: MockBackend, s: CellService ) => {
            ...
    
            let value;
            s.getCell('powders').subscribe(val => {
              value = val;
            })
            tick();
            expect(val).toBeTruthy();
        })
    ));
    

    应该async一起工作,但使用fakeAsync会使调试更容易一些,因为每件事都是同步的。

    如果它仍然不起作用,那么您可能需要在其他地方检查逻辑。我要做的检查之一就是这里

    req.method === RequestMethod.Get && req.url === '/api/getTest'
    

    你确定这两个都通过了吗?如果没有,将不会有任何回应。

    【讨论】:

    • 查看我更新的问题,我尝试了这种方法,但仍然没有看到预期的行为,我做错了什么吗?
    • 查看我的更新。确保条件通过。如果没有,将不会有任何回应。
    【解决方案2】:

    我更喜欢在这里使用 Jasmine done() 回调。

    首先,去掉规范中的注入器,在beforeEach 部分使用TestBed.get(serviceToken)

    其次,将done作为spec函数的参数传递

    it('should use asynchronous', done => {
      s.method().subscribe(result => {
        expect(result).toBe(...);
        done();
      }
    })
    

    【讨论】:

      猜你喜欢
      • 2018-06-13
      • 2018-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多