2

I am having trouble asserting that my filter has been called after a promise has been returned.

This code is called from a controller which then pulls the data to filter from a http GET service:

getPermissions(){
    return this.DataService.getPermissionsLOV().then((data) => {
        return this.$filter('chunkCollection')(data, 3);
    });
}

My test case looks like so:

it('should get the permissions', () => {
    spyOn(service, 'getPermissions').and.callThrough();
    spyOn(DataService, 'getPermissionsLOV').and.callFake(function(){
        var defer = this.$q.defer();
        defer.resolve(mockData);
        return defer.promise;
    });

    let resp;

    service.getPermissions().then((data) => {
        resp = data;
    });

    scope.$digest();

    expect(service.getPermissions).toHaveBeenCalled();
    expect(DataService.getPermissionsLOV).toHaveBeenCalled();
    expect(resp).toEqual(mockData);

});

The assertion expect(resp).toEqual(mockData); fails as the response is filtered by chunkCollection but I do not know how to test this call to $filter?

I have tested the filter itself separately so know that is working and karma tells me it is transforming the data when reporting the failure of the aforementioned assertion.

RyanP13
  • 7,413
  • 27
  • 96
  • 166

2 Answers2

5

I think your question is really how to mock a filter. You can just add a beforeEach and provide the filter before your test.

var mockChunkCollectionFilter = jasmine.createSpy('chunkCollectionFilter');
beforeEach(module(function($provide) {
  $provide.value('chunkCollectionFilter', mockChunkCollectionFilter);
}));

it('should get the permissions', () => {
    spyOn(service, 'getPermissions').and.callThrough();
    spyOn(DataService, 'getPermissionsLOV').and.callFake(function(){
        var defer = this.$q.defer();
        defer.resolve(mockData);
        return defer.promise;
    });
    mockChunkCollectionFilter.and.callFake(function (data, chunks) {
      // Ignore chunks since that's what the test expects.
      return data;
    });

    let resp;

    service.getPermissions().then((data) => {
        resp = data;
    });

    scope.$digest();

    expect(service.getPermissions).toHaveBeenCalled();
    expect(mockChunkCollectionFilter).toHaveBeenCalled();
    expect(DataService.getPermissionsLOV).toHaveBeenCalled();
    expect(resp).toEqual(mockData);

});

mockChunkCollectionFilter works just like your other spies.

Yunchi
  • 5,529
  • 2
  • 17
  • 18
  • How would I integrate that into the test case? Sorry am new to this so struggling a bit. – RyanP13 Aug 13 '15 at 05:47
  • @RyanP13 sure, expanded my answer. Let me know if that helps – Yunchi Aug 13 '15 at 13:31
  • Thank you! I've been looking for an example like this. One of the few examples I've seen that shows how to mock a filter and use callFake within the it function so that the filter could return different values in different scenarios. – jsparks Dec 01 '16 at 14:19
1

Since you know what the mock response is and you also know what the filter is, you know how many rows will the filter return if the filter is working correctly. You just need to assert that the resolved collection contains the exact items and count after the filter is done. If the filter has worked correctly this data will match.

Chandermani
  • 42,589
  • 12
  • 85
  • 88