physicsboy
physicsboy

Reputation: 6348

Angular - Testing an @Input with a set attached to it

I have a component which takes an argument as a sort of directive to set the size of the <div> within its template, the only problem now is that I am unsure how to test it?

I called my component like this, where small can be replaced with other pre-defined sizes such as medium/large etc:

<spinner small></spinner>

Then I take this as an @Input(<size>) and perform a set to change a size variable that is then passed into an [ngStyle] to change the CSS of the displayed component size.

component.ts

size: number;

@Input('small') set small(value) {
  this.size = !value ? 25 : this.size;
}

get getSize() {
  const myStyle = {
    width: this.size + 'px',
    height: this.size + 'px'
  };
  return myStyle;
}

component.html

<div [ngStyle]="getSize"></div>

I have successfully tested the get getSize() function, but I have become a bit stuck around the @Input(<val>) set functions :-/

Upvotes: 3

Views: 3987

Answers (2)

user4676340
user4676340

Reputation:

To know what test to make, ask yourself this question :

What does my [feature/component/service/function/variable/...] do ?

In this case, your setters can answer with

As a setter with an Input decorator, I should set the value of the size variable if my own value is undefined. If my own value is defined, I should fall back to the default value.

This means that your setter tests will look like this :

it('should set size variable with value undefined', () => {
  component.size = 10;
  component.small = '';
  epxect(component.size).toEqual(25);
});

it('should not change size variable with value defined', () => {
  component.size = 10;
  component.small = 'ff';
  epxect(component.size).toEqual(10);
});

Upvotes: 5

shokha
shokha

Reputation: 3179

Stackblitz demo

In order to spyOn getter/setter properties, you can use jasmine spyOnProperty:

enter image description here

So in your example we have: obj -> component, propertyName -> 'small', accessType -> 'set' :

  it('call small setter method', () => {
    const small = spyOnProperty(component, 'small', 'set'); // just spyOn setter method of small
    component.size = 10; // set initial value of size to 10

    component.small = 'large'; // set small property which as expected - should call setted method

    // we expect that `small` setter method will be called 
    //  with 'large' argument, since we setted it before 
    expect(small).toHaveBeenCalledWith('large'); 

    // we also expect, that the logic of your setter method works correctly: `this.size = !value ? 25 : this.size;`
    // since we pass value, your `this.size` will not change
    expect(component.size).toBe(10); 
  });

Edit

This is another test in case when we pass to setter argument an empty string:

it('call small setter method 2', () => {
    const small = spyOnProperty(component, 'small', 'set').and.callThrough();

    component.small = '';

    expect(small).toHaveBeenCalledWith('');
    expect(component.size).toBe(25);
  });

As expected - the small setter will be called with '' empty string and the size property will be 25 because of this: this.size = !value ? 25 : this.size;

Upvotes: 1

Related Questions