angulartestingng-mocks

Is it possible to preserve some methods from a mocked service with ng-mocks?


I'm adding tests to an angular project. There is a service which is getting some data from an API and create some business entity from this data.

I mocked this service to test a component which depends on it, using ng-mocks.

The original service looks like:

class DataService {
  public getEntityFromApi(): Observable<Entity> {
    return http.get(...).pipe(
      map(httpResponse => {
        return this.createEntityFromApiData(httpResponse);
      })
    );
  }

  private createEntityFromApiData(apiData: any): Entity {
    // ...
  }
}

It is mocked with:

getMockedServiceProvider() {
  const testData = ...;
  return MockProvider(DataService, {
    getEntityFromApi: () => {
      let entity = // duplicated code from the createEntityFromApiData method to create the object from testData
      return of(entity);
    }
  });
}

So the mocked service is able to return an object without making a request to the API, but I had to duplicate the code that creates the object from the plain json.

What would be the best way to avoid this duplication in the mocked service?

  1. Is it possible somehow to preserve the private createEntityFromApiData from the original service in the mocked one?
  2. Should I isolate this logic in another service responsible solely for the instantiation which I would use as-is in my test?
  3. Other method?

Solution

  • In your case if you want to preserve something from the service, then there are 2 options:

    1. Preserve the service itself
    2. Extract the thing into a separate class / function.

    If you want to return the same fake data in all tests you might consider usage of ngMocks.defaultMock.

    Then you would need to call it once in src/test.ts.

    ngMocks.defaultMock(DataService, () => ({
      getEntityFromApi: () => {
        let entity = // duplicated code from the createEntityFromApiData method to create the object from testData
        return of(entity);
      },
    }));