angular2测试:直接调用函数不能改变组件对象本身

时间:2017-08-04 17:46:30

标签: angular unit-testing jasmine karma-jasmine

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

以下是代码的一部分:

组件:

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

问题在于,如果我使用setStarFlag直接调用函数component.setStarFlag(true, false),则函数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

任何人都可以向我解释为什么以及如何解决这个问题(我正在考虑使用隔离单元测试,但我想配置将是很多工作,因为我有服务)?

2 个答案:

答案 0 :(得分:4)

如果您希望正常调用spied-upon函数,请将BEGIN value1 value2 value3 SPEC1 some_other_line1 BEGIN value1 value2 value3 value4 SPEC1 some_other_line2 BEGIN value1 value2 SPEC1 添加到您的间谍语句中。

您应该致电.and.callThrough()

spyOn(component, 'setStarFlag').and.callThrough();

答案 1 :(得分:0)

我终于找到了问题所在。

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

遇到同样问题的人

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

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