angular 茉莉花用不同的参数测试间谍

angular jasmine testing an spy with different arguments

我正在学习测试的基础知识,我正在使用我用 Angular 和 Firebase 开发的聊天工具。

我有一种方法可以根据不同的提供商对用户进行身份验证。提供商的名称将作为参数传递。它将调用服务上的另一个方法,这将使逻辑成为可能。

authentication() 将在我们按下按钮时调用,这样使用 google 登录的按钮将调用 authentication('google') ,使用 facebook 登录的按钮将是 authentication ('facebook')等等。

login.component.ts

 authenticate(provider:String){

    
      this._chat.login(provider).then(()=>{
      }).catch((error)=>{
        console.log ("something went wrong with the authenticate method", error);
      });
 
    
  }

为了进行测试,我在该方法上创建了一个 spy,并试图重新创建不同的点击。当我做类似

的东西时
spyOn(component, 'authenticate').withArgs('google');
buttonElement.click();
expect(component.authenticate).toHaveBeenCalledWith('google');

但是当我用不同的参数进行另一个测试时:

spyOn(component, 'authenticate').withArgs('facebook');
buttonElement.click();
expect(component.authenticate).toHaveBeenCalledWith('facebook');

它抛出一个错误,因为它似乎调用了它第一次调用的参数:

我一直在调查并尝试使用建议的解决方案 但它不起作用。

正如您在下面的代码中看到的,我正在重置 beforeEach().

中的间谍程序

如何在每次使用间谍时使用不同的参数并使其工作?我还有什么地方做错了吗?

这是完整的规范代码。

login.component.spec.ts

import { ComponentFixture, TestBed } from '@angular/core/testing';

import { LoginComponent } from './login.component';
import { ChatService } from '../../services/chat-service/chat.service';
import { DebugElement } from '@angular/core';
import { AngularFireModule } from '@angular/fire/compat';
import { environment } from 'src/environments/environment';
import { RouterTestingModule } from '@angular/router/testing';

describe('LoginComponent', () => {
  let component: LoginComponent;
  let fixture: ComponentFixture<LoginComponent>;
  let debugElement: DebugElement;
  let _chat:ChatService;
  let buttonElement:HTMLButtonElement;
  let spy1:any; 
   
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ LoginComponent ],
      imports:[RouterTestingModule,
        AngularFireModule.initializeApp(environment.firebase),
      ],
      providers: [ChatService]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(LoginComponent);
    debugElement = fixture.debugElement;
    _chat=debugElement.injector.get(ChatService);
    component = fixture.componentInstance;
    buttonElement = fixture.debugElement.nativeElement.querySelector('.button-login');
   spy1=spyOn(component, 'authenticate');

   spy1.calls.reset();


    
  });

  it('should click google button and call authenticate method with google', () => {

    spy1.withArgs('google');
    buttonElement.click();
    expect(component.authenticate).toHaveBeenCalledWith('google');
   
  });

  it('should click facebook button and call authenticate method with facebook', () => {

 
    spy1.withArgs("facebook"); 
    buttonElement.click();
    expect(component.authenticate).toHaveBeenCalledWith('facebook');
   
  });


  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

我不明白是什么在控制 authenticategooglefacebook 调用,我假设它们是不同的按钮。

如果是这种情况,您需要对特定按钮元素的新引用。

it('should click google button and call authenticate method with google', () => {

    spy1.withArgs('google');
    // get the google button element
    const googleButton = fixture.debugElement.query(By.css('button#google')).nativeElement;
    googleButton.click();
    expect(component.authenticate).toHaveBeenCalledWith('google');
   
  });

  it('should click facebook button and call authenticate method with facebook', () => {

 
    spy1.withArgs("facebook"); 
    const facebookButton = fixture.debugElement.query(By.css('button#facebook')).nativeElement;
    facebookButton.click();
    expect(component.authenticate).toHaveBeenCalledWith('facebook');
   
  });

确保每个按钮都有唯一的选择器 (id="facebook", id="google") 否则 By.css('.button-login') 会找到它在 HTML 匹配 .button-login.

中找到的第一个元素