Jasmine check if private method has been called

Viewed 6789

I have an Angular service exposing a public method. Inside its body two different private methods can be called according to a condition.

How can I check with jasmine whether one or the other method has been called, according to the input parameter passed to the public method? I know we should not test private methods, but indeed here I just want to verify whether the public one calls the right private method. I do not want to make the private methods public, as I want only one point of access provided by the service.

My service methods:

public  addOrUpdateShoppingList(list: ShoppingList) {
  if (!list) {
    return Promise.reject("List object is null!");
  }

  if (!list.id) { 
    return this.createNewList(list);
  }

  return this.updatelist(list);
}

private createNewList(list: ShoppingList) {
  const id = this.db.createId();
  list.id = id;
  return this.db.collection<ShoppingList>(this.SHOPPING_LIST_COLLECTION)
                .doc(id)
                .set(list);
}

private updatelist(list: ShoppingList) {
  return this.db.collection<ShoppingList>(this.SHOPPING_LIST_COLLECTION)
                .doc(list.id)
                .update(list);

}

Jasmine test:

it("addOrUpdateShoppingList should invoke createNewList() if the list doesn't have id.", () => {
const service: DataService = TestBed.get(DataService);
const mockedList: ShoppingList[] = [
  {
    id: null,
    isActive: true,
  }
 ];

service.addOrUpdateShoppingList(newList);

// I tried even with this "workaround", but it fails, even if the private method is accessed
const sp = spyOn<any>(service, "createNewList").and.callThrough();
expect(sp).toHaveBeenCalled();

});

1 Answers

You can't test the private methods directly - after all that is the POINT of private methods: they can't be seen outside the class in which they are defined. For a couple of work-arounds see this Stack Overflow question.

However in your case you are in luck. Both of your private methods make a call to the database service. Simply spy on that service call and test what was passed - are you trying to set or to update - this will determine which inner private method was called.

Related