RasMason
RasMason

Reputation: 2212

Testing a function that uses a service Jasmine spyOnObject

I'm trying to test a function that is initiated by a button click

If the button value equals "Yes" apply a custom validator to a formGroup

The validator requires a parameter which is a service "this.stateService", which returns a number "0" for this test.

Actual function:

  onSelected(): void {
        const myFormGroup: AbstractControl = this.form.controls.fGroup;
            if (this.form.get('button').value === 'Yes') {
                myFormGroup.validator = myValidation.requireCheckboxesToBeChecked(this.stateService);
                } else {
                myFormGroup.setValidators(null);
                }
            myFormGroup.updateValueAndValidity();
    }

In the validator file:

static requireCheckboxesToBeChecked(stateService: StateService): ValidatorFn {
    return function validate (formGroup: FormGroup): { [key: string]: boolean } | null  {
      const checkedCount = stateService.currentCheckedCount();
      if (checkedCount === 0) {
          return  {
            'isNotChecked' : true
          };
        }
      return null;
    };
  }

The test function:

import { myValidation } from '@app/shared/validators/modification.validator';

const mockStateService = jasmine.createSpyObj('StateService',
    [ 'getCategoryState',
      'getCheckedCount'
    ]);

  it('should add validation to my form group when value is Yes', () => {

    const vehicleModificationsFormGroup = component.form.controls['vehicleModifications'];

    component.form.get('button').setValue('Yes');
    component.onSelected();

    myFormGroup.validator = myValidation.requireCheckboxesToBeChecked(mockStateService);
    expect(mockStateService.currentCheckedCount).toEqual(0);
    expect(myFormGroup.validator.length).toBe(1);
  });

I'm getting "stateService.currentCheckedCount is not a function" which is in the validator file

Upvotes: 1

Views: 1152

Answers (2)

RasMason
RasMason

Reputation: 2212

@stp18's answer put me on the right track, the function was missing from the array

However, I did have to modify the call to the mockService to return a value, rather than be equal to

    import { myValidation } from '@app/shared/validators/modification.validator';

    const mockStateService = jasmine.createSpyObj('StateService',
             [ 'currentCheckedCount',
               'getCheckedCount'
             ]);

    it('should add validation to my form group when value is Yes', () => {

    const vehicleModificationsFormGroup = component.form.controls['vehicleModifications'];

    component.form.get('button').setValue('Yes');
    component.onSelected();

    myFormGroup.validator = myValidation.requireCheckboxesToBeChecked(mockStateService);
    mockStateService.currentCheckedCount.and.returnValue(0);
    expect(myFormGroup.validator.length).toBe(1);
  });

Upvotes: 1

stp18
stp18

Reputation: 311

The mock you are defining (mockStateService) doesn't have a currentCheckedCount method.

The mockStateService does only have two methods getCategoryState and getCheckedCount.

If you want to mock just some methods of an object, you could try spyOn on an instance of ExampleService.

And so on, there are another options to spy/mock some methods.

You can also try to define what you want to return using createSpyObj:

const mockStateService = jasmine.createSpyObj('StateService',  
    { 
       getCategoryState: function() {
          return "ifItMathersReturnSomething";
       },
       getCheckedCount: function() {
          return "anotherThing";
       },
       currentCheckedCount: function() {
          return 0;
       } 
   }
);

Upvotes: 3

Related Questions