【问题标题】:Angular - Testing an @Input with a set attached to itAngular - 使用附加的集合测试@Input
【发布时间】:2018-08-31 08:47:51
【问题描述】:

我有一个组件,它接受一个参数作为一种指令来在其模板中设置<div> 的大小,现在唯一的问题是我不确定如何测试它?

我这样调用我的组件,其中small 可以替换为其他预定义的大小,例如medium/large 等:

<spinner small></spinner>

然后我将其作为@Input(&lt;size&gt;) 并执行设置以更改大小变量,然后将其传递给[ngStyle] 以更改显示组件大小的CSS。

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>

我已经成功测试了get getSize() 函数,但是我对@Input(&lt;val&gt;) set 函数有点卡住了:-/

【问题讨论】:

    标签: javascript angular typescript testing karma-runner


    【解决方案1】:

    要知道要进行什么测试,请问自己这个问题:

    我的 [feature/component/service/function/variable/...] 有什么作用?

    在这种情况下,你的 setter 可以用

    来回答

    作为带有Input 装饰器的设置器,如果我自己的值未定义,我应该设置size 变量的值。如果定义了我自己的值,我应该回退到默认值。

    这意味着您的 setter 测试将如下所示:

    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);
    });
    

    【讨论】:

      【解决方案2】:

      Stackblitz demo

      为了监视 getter/setter 属性,你可以使用jasmine spyOnProperty:

      所以在你的例子中我们有:obj -&gt; component, propertyName -&gt; 'small', accessType -&gt; '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); 
        });
      

      编辑

      这是另一个测试,以防我们将空字符串传递给 setter 参数:

      it('call small setter method 2', () => {
          const small = spyOnProperty(component, 'small', 'set').and.callThrough();
      
          component.small = '';
      
          expect(small).toHaveBeenCalledWith('');
          expect(component.size).toBe(25);
        });
      

      正如预期的那样 - small setter 将使用 '' 空字符串调用,size 属性将是 25,因此:this.size = !value ? 25 : this.size;

      【讨论】:

      • 我不确定...我的意思是,它通过了;但是测试设置大小然后调用大小?像component.size = 10 然后expect(component.size).toEqual(10)...当然会是10。或者这只是它应该做的方式,因为这就是@Input() 所做的一切?我可能只是很密集:P - 另外,我不知道您可以在 stackblitz 上进行测试!太棒了!
      • “但是测试设置了大小,然后调用了大小”——你说的调用大小是什么意思?没有任何电话。我已经编辑了答案并添加了解释,请查看。
      • 啊,我从代码中的 cmets 现在所说的内容中了解更多!这更有意义。
      • 我会说你的测试是 "too specific" :这确实是编写测试的“正确方法”,但你依赖于 getter 的实现和打字稿的二传手。单元测试的目的是测试单个单元并对其他代码进行抽象,在这种情况下,您正在测试 Typescript 是否完成了它的工作(这不是您的工作)
      • @sherlock.92 这就是我没有投反对票的原因:您的回答在技术上是有效的,我只是根据我自己的所学发表意见!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-16
      • 1970-01-01
      • 2017-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-05
      相关资源
      最近更新 更多