【问题标题】:Checking local variable while unit testing on a component in Angular gives error在 Angular 中对组件进行单元测试时检查局部变量会出错
【发布时间】:2020-04-12 19:04:24
【问题描述】:

假设有 2 个组件:AppComponent 和 TestComponent。我在 AppComponent 的 HTML 模板中使用它的指令调用 TestComponent。现在 TestComponent 有一个 @Input() 属性(让它成为 myTitle )。

我只对 TestComponent 进行单元测试。对于标题,我在测试本身中传递了一个随机值。这是相同的代码:

app.component.html

<span><app-test [myTitle]="title"></app-test></span>

app.component.ts

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})

export class AppComponent{
    title = {name: 'hello-world'};
}

test.component.html

<p>test works!!{{myTitle.name}}</p>
<button (click)="onClick()">Click Please !!!</button>

test.component.ts

@Component({
    selector: 'app-test',
    templateUrl: './test.component.html',
    styleUrls: ['./test.component.css']
})

export class TestComponent implements OnInit{
    @Input() myTitle;
    filter;
    constructor(){

    }

    ngOnInit():void{
        this.myTitle.name = "Hi!!";
    }
    onClick(){
       this.filter="GokuSSj3";
    }
}

test.component.spec.ts

describe('Test component',() =>{
    let temp;
    let component: TestComponent;
    let fixture: ComponentFixture<TestComponent>;

    beforeEach(async(() =>{
       TestBed.configureTestingModule({
           declarations: [TestComponent],
           schemas: [NO_ERRORS_SCHEMA]
       }) 
       .compileComponents();
    }));

    beforeEach(()=>{
        temp = {name: "Heloooo"};
       fixture = TestBed.createComponent(TestComponent);
       component = fixture.componentInstance;
    });

    it('should check First',()=>{
       component.myTitle = temp;
       console.log(component.myTitle.name);
       console.log(temp.name);

       fixture.detectChanges();

       console.log(component.myTitle.name);
       console.log(temp.name);
       expect(component.myTitle.name).toEqual(temp.name);
    });

    it('should check whether onClick is called on button click or not and also the value of filter',()=>{
       component.myTitle = temp;
       spyOn(component,'onClick');
       fixture.detectChanges();

       let btn = fixture.debugElement.query(By.css('button'));
       btn.triggerEventHandler('click',null);

       fixture.whenStable().then(()=>{
          expect(component.onClick).toHaveBeenCalled();
          expect(component.filter).toEqual("GokuSSj3");
    });
});

第二个测试用例显示错误:Expected undefined to equal 'GokuSSj3'。为什么会这样?即使 onClick 已被调用。

我是这个社区的新手,所以如果有任何失败,请帮助我改进问题。

【问题讨论】:

  • 我打赌应该是component.filter而不是component.fixture
  • 是的。为疏忽道歉。所做的更改。谢谢。
  • 再次评论您提供的类似问题,测试按钮触发 onClick 事件没有意义。您基本上是在测试库甚至是较低级别的 HTML 按钮。您可以确定,当您单击一个按钮时,它会触发一个 onClick 事件。你不需要测试它。您应该测试您生成的代码的行为。不是 HTML 组件的行为
  • 好的,非常感谢。那么我该如何修复未定义的错误呢?

标签: angular typescript unit-testing


【解决方案1】:

由于您在 onClick 函数上添加了 spy,它永远不会触发和更新过滤器的值。

您需要删除该间谍功能并查看实际值的变化。

更改测试如下:

it('should check whether onClick is called on button click or not and also the value of filter', () => {
      component.myTitle = temp;
      fixture.detectChanges();

      let btn = fixture.debugElement.query(By.css('button'));
      btn.triggerEventHandler('click', null);

      fixture.whenStable().then(() => {
        expect(component.filter).toEqual("GokuSSj3");
      });

【讨论】:

  • 非常感谢 Gaurav。但为什么它不能与 spyOn 一起使用?是不是因为 spyOn 只是拦截了函数调用?
  • spyOn 模拟事件并绕过实际实现
  • 如果您对您的回复没有问题,那么您应该将该回复标记为答案,以帮助其他寻求相同解决方案的人
  • 完成。现在还好吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-21
  • 1970-01-01
  • 1970-01-01
  • 2020-02-13
  • 2014-01-23
相关资源
最近更新 更多