简体   繁体   English

如何测试角度数据缓存?

[英]How to test angular data caching?

I have an angular service that talks to our API. 我有一个与我们的API对话的角度服务。 Certain requests for the same data can be cached locally to help things feel a bit faster. 可以在本地缓存对相同数据的某些请求,以帮助感觉更快一些。

Here's basically what's going on in a service method that does some caching: 这基本上是在进行一些缓存的服务方法中发生的事情:

private thingCache: IThing[] = [];

getThing$(thingId: string): Observable<IThing> {
    const cachedThing = this.thingCache.find(( => l.id === thingId);
    if (cachedThing) {
        return of(cachedThing);
    }
    const fetchedThing$ =  this.http.get<IThing>(`http://our-api/thing/${thingId}`)

    .pipe(tap((thing: IThing) => {
        //add any retrieved login to the cache
        //we already checked above that it's not in the cache, so we know we are adding a new one here
        this.thingCache.push(thing);
    }));

    return fetchedThing$;
}

So In a test I need to test that the first call comes from an actual HTTP GET request, and any call after that does not. 所以在测试中我需要测试第一个调用是来自实际的HTTP GET请求,之后的任何调用都没有。 What's the best way to do this? 最好的方法是什么?

Here's how I test the first call, which does work 这是我测试第一个调用的方法,它确实有效

describe('Service: api', () => {
    let service: ApiService;
    let httpMock: HttpTestingController;

    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [ HttpClientTestingModule ],
            providers: [ ApiService ]
        });
        service = TestBed.get(ApiService);
        httpMock = TestBed.get(HttpTestingController);
    });

    afterEach(() => {
        httpMock.verify();
    });

    it('should GET a thing when calling getThing$() with a thing ID', () => {
        service.getThing$('1234-5678-9012').subscribe((value: IThing) => {
            expect(value).toEqual({
                id: '148e265b-b284-84b7-b8b3-441854f15783', otherData: 'foo'
            } as IThing);
        }, () => {
            fail('The subscription to getThing$() has errored out!');
        });

        const req = httpMock.expectOne('http://our-api/thing/1234-5678-9012');
        expect(req.request.method).toEqual('GET');

        req.flush({
            id: '148e265b-b284-84b7-b8b3-441854f15783', otherData: 'foo'
        } as IThing);
    });
});

Well, this turned out to be a bit simpler than I thought it would be. 嗯,事实证明这比我想象的要简单一些。 just unsubscribe, and then do it again. 只是取消订阅,然后再做一次。

it('should return a thing from the API on the first call, and from cache on the 2nd call for the same data', () => {
    const sub1 = service.getThing$('148e265b-b284-84b7-b8b3-441854f15783').subscribe((value: IThing) => {
        expect(value).toEqual({
            id: '148e265b-b284-84b7-b8b3-441854f15783', otherData: 'foo'
        } as IThing);
    }, () => {
        fail('The subscription to getThing$() has errored out!');
    });

    const req = httpMock.expectOne('http://our-api/thing/148e265b-b284-84b7-b8b3-441854f15783');
    expect(req.request.method).toEqual('GET');

    req.flush({
        id: '148e265b-b284-84b7-b8b3-441854f15783', otherData: 'foo'
    } as IThing);

    //----------------------------------------------------------------------
    //Ensure a 2nd call for the same ID does not make an HTTP call

    sub1.unsubscribe();

    const sub2 = service.getThing$('148e265b-b284-84b7-b8b3-441854f15783').subscribe((value: IThing) => {
        expect(value).toEqual({
            id: '148e265b-b284-84b7-b8b3-441854f15783', otherData: 'foo'
        } as IThing);
    }, () => {
        fail('The subscription to getThing$() has errored out!');
    });

    httpMock.expectNone('http://our-api/thing/148e265b-b284-84b7-b8b3-441854f15783');

    //----------------------------------------------------------------------
    //Ensure a 3rd call for a DIFFERENT ID still makes an HTTP request for the new un-cached data

    sub2.unsubscribe();

    service.getThing$('111e2222-bbbb-8888-cccc-444455555777').subscribe((value: IThing) => {
        expect(value).toEqual({
            id: '111e2222-bbbb-8888-cccc-444455555777', otherData: 'bar'
        } as IThing);
    }, () => {
        fail('The subscription to getThing$() has errored out!');
    });

    const req3 = httpMock.expectOne('http://our-api/thing/111e2222-bbbb-8888-cccc-444455555777');
    expect(req3.request.method).toEqual('GET');

    req3.flush({
        id: '111e2222-bbbb-8888-cccc-444455555777', otherData: 'bar'
    } as IThing);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM