mercredi 23 novembre 2016

Jasmine: Testing a function returning a promise``

I am writing tests using Jasmine for my angular application. All the tests are passing. My class looks like follows:

class xyz implements ng.IComponentController {
  private myList: ng.IPromise<MyList[]> ;
  //declare necessary variables
  /* @ngInject */
  constructor(private ListService: ListService,
              ) {
    this.myList = this.ListService.getList();
  }

  public onChange(): void {
    this.isNameUnique(this.name).then(function(unique){
      scope.isUnique = unique;
      scope.errorNameInput = !reg.test(scope.name) || !scope.isUnique;
      scope.myFunction({
        //do something
      });
    });
  }

  public isNameUnique(name: string): ng.IPromise<boolean> {
    return this.myList
    .then(
      (names) => {
        _.mapValues(names, function(name){
          return name.uuid.toLowerCase();
        });
        return (_.findIndex(names, { uuid : uuid.toLowerCase() }) === -1) ?  true : false;
    });
  }
}

Here, I am using ListService to pre-populate my list in the constructor itself (so it calls the service only once). Then, in my onChange method, I am checking if a name is unique or not. The isNameUnique is returning a boolean promise. Now, I'm trying to get 100% coverage for my test. I'm getting confused about testing isNameUnique method here. My first test is:

(Assuming myList is a json similar to response I will get from service)

 this.$scope.myFunction = jasmine.createSpy('myFunction');
    it('should ...', function() {
      this.view.find(NAME_INPUT).val('blue').change(); // my view element.
      this.getList.resolve(myList);
      this.controller.isNameUnique('blue').then(function (unique) {
        expect(unique).toEqual(false); //since blue is already in my json
        expect(this.controller.errorNameInput).toEqual(true); //since its not unique, errornameinput will be set to true
        expect(this.$scope.myFunction).toHaveBeenCalled();
      });
    });

I would expect this test to cover the line: scope.errorNameInput = !reg.test(scope.name) || !scope.isUnique and invocation of myFunction() but it still shows uncovered. Not sure why.

Another question: I'm not sure how to test the part:

_.mapValues(names, function(name){
   return name.uuid.toLowerCase();
 });

in isNameUnique(). I'd expect that if my JSON has some mixed case words, this part would automatically be covered with the following test, but it didn't:

it('should return false if uuid already exists', function() {
  this.view.find(NAME_INPUT).val('blUE').change();
  this.getList.resolve(myList);
  this.controller.isNameUnique('blUE').then(function (unique) { //assuming my json has BLUE already stored, so ignoring case, both are equal, hence not unique
    expect(unique).toEqual(false);
  });
});

Please let me know if you see anything else wrong since I'm quite new to Angular and Jasmine. Thanks.

Aucun commentaire:

Enregistrer un commentaire