【问题标题】:angular2 testing: calling function directly cannot change the component object itselfangular2测试:直接调用函数不能改变组件对象本身
【发布时间】:2017-08-04 17:46:29
【问题描述】:

我正在为 angular2/4 应用程序编写单元测试。我编写了一个函数单元测试,它基本上调用一个函数并期望组件对象的属性发生变化。

以下是部分代码:

组件:

export class LoginComponent{

  constructor(private loginService: LoginService){}; 

  noUsername: boolean= false; 
  noPassword: boolean= false; 

  setStarFlag(id:boolean, pw:boolean){
      this.noUsername = id;
      this.noPassword = pw;
  }

}

单元测试:

var fixture: ComponentFixture<LoginComponent>,
    component: LoginComponent,
    loginService: LoginService, 
    loginServiceStub: LoginServiceStub;

describe('LoginComponent', () => {

beforeEach(async(() => {

    //set up testing environment
    TestBed.configureTestingModule({

        declarations: [LoginComponent],

        providers: [
                    { provide: HttpModule, useValue: true }, 
                    { provide: Http, useValue: true }, 
                    { provide: Router, useValue: true },
                   ] 

    }).overrideComponent(LoginComponent, {
        set: {
            //override original service with a stub one
            providers: [
                { provide: LoginService, useClass: LoginServiceStub},
                { provide: ActivatedRoute, useValue: { params: Observable.of({resumePath: 'testpath'})} }
            ]
        }
    }).compileComponents().then(() => {

        fixture = TestBed.createComponent(LoginComponent); //end testbed config & create fixture that provides access to component instance itself

        component = fixture.componentInstance; //getting component itself

        loginService = fixture.debugElement.injector.get(LoginService); 

    });

}));


describe('function setStarFlag', ()=>{

    it('set the flag to the right values', ()=>{

        spyOn(component, 'setStarFlag');

        component.setStarFlag(true, false);

        expect(component.noUsername).toBeTruthy(); //this doesnt work
        expect(component.noPassword).toBeFalsy();  //this doesnt work
    })
});

问题是如果我直接使用component.setStarFlag(true, false)调用函数setStarFlag,函数setStarFlag不能改变组件本身的属性noUsernamenoPassword

但是假设我通过模拟按钮单击来触发该功能,noUsernamenoPassword 属性将发生变化。

HTML 文件:

<button (click)="setStarFlag(true, false)"></button>

单元测试:

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

expect(component.noUsername).toBeTruthy(); //this works 
expect(component.noPassword).toBeFalsy(); // this works

谁能向我解释为什么以及如何解决这个问题(我在考虑使用独立的单元测试,但我想配置会做很多工作,因为我有服务)?

【问题讨论】:

    标签: angular unit-testing jasmine karma-jasmine


    【解决方案1】:

    如果您希望被窥探的函数能够正常调用,请将.and.callThrough() 添加到您的 spy 语句中。

    您应该致电spyOn(component, 'setStarFlag').and.callThrough();

    component.setStarFlag(true, false);

    【讨论】:

      【解决方案2】:

      我终于知道问题出在哪里了。

      因此,如果我们监视函数,jasmine spy 将存根被监视的函数以进行监视。在这种情况下,该功能将失去其真正的功能。如果我们从我的代码中删除spyOn 函数,它将完美运行!

      致遇到同样问题的人:

      使用两个单独的规范来测试功能和函数调用。

      来源:https://jasmine.github.io/2.0/introduction.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-12
        • 2020-07-17
        • 2017-09-15
        • 1970-01-01
        • 2016-06-15
        • 1970-01-01
        相关资源
        最近更新 更多