javascript - 如何在 jasmine 中测试一个函数

标签 javascript angular testing jasmine

谁能帮帮我?我正在尝试测试调用 firebase 函数的函数,但是当我调用 main 函数并开始运行 firebase 函数时,出现错误

err TypeError: Cannot read property 'emailPasswordLoginAsPromise' of null

我不知道发生了什么,按照我的代码:

fdescribe('UserLoginContentComponent', () => {
  let component: UserLoginContentComponent;
  let fixture: ComponentFixture<UserLoginContentComponent>;
  let loginComponent = new UserLoginContentComponent(null,null,null,null,null,null,null);
  
  beforeAll(
    async(() => {
      TestBed.configureTestingModule({
        imports: [
          SharedModule,
          AngularFireModule.initializeApp(environment.firebase),
          RouterTestingModule,
          BrowserAnimationsModule
        ],
        declarations: [UserLoginContentComponent],
        providers: [ 
          AuthService,
          AngularFireAuth,
          AngularFirestore,
          LogService,
          LogPublishersService,
          HttpClient,
          HttpHandler
        ]
      }).compileComponents();

      fixture = TestBed.createComponent(UserLoginContentComponent);
      component = fixture.componentInstance;
      fixture.detectChanges();

      spyOn(loginComponent, 'onSubmit').and.callThrough();
      loginComponent.loginModel.email = 'correct email';
      loginComponent.loginModel.password = 'correct password';
    })
  );

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

  it('Correct login',function(){
    loginComponent.onSubmit().then((x) => {
      console.log('ok:',x)
      //expect something ..
    }).catch((err) => {
      console.log('err',err)
    })
  });
    
});

我正在调用的函数:

onSubmit() {
    //i'm setting my loginModel in the test with email and password
    console.log('this.loginModel',this.loginModel)

    return new Promise((res,rej) => {
      this.authService.emailPasswordLoginAsPromise(this.loginModel).then(userCredential => {
      // do something..
        this.authService.createOrUpdateUserDataFirestore(userCredential, null, avaliacaoChecklist, null, null).then(s => 
        //updating my user or create one
        }).catch(e => {
          //catch if this doesn't update or create
          });
        });
        res('login OK')
      }).catch(e => {
        //open a diaglog if happen something wrong...
        rej('login Fail')
      });
    })
  }

在我的 authService 中,我的 emailloginasPromise 是这样的:

  emailPasswordLoginAsPromise(login) {

    return new Promise((resolveEPL, rejectEPL) => {

      this.angularFireAuth.auth.signInWithEmailAndPassword(login.email, login.password)
        .then(credential => {
          this.updateUserWithAuth(credential.user);
          resolveEPL(credential.user);
        }).catch(e => {
          console.error('emailPasswordLogin', e);
          rejectEPL(e);
        });
    });
  }

这是我第一次测试 jasmine,我学习了,但我不知道如何解决这个问题,如何调用异步函数并获得返回值。

最佳答案

我发现了问题,请按照修复方法进行操作:

当我创建我的类(class)的立场时,没有提供 authService,所以现在我正在使用该组件:

component = fixture.componentInstance;

现在我使用这个组件调用我的方法,所有提供者都在工作。

按照我的描述:

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { SharedModule } from '../../shared/shared.module';
import { UserLoginContentComponent } from './user-login-content.component';
import { AngularFireModule } from '@angular/fire';
import { environment } from 'src/environments/environment';
import { RouterTestingModule } from '@angular/router/testing';
import { AuthService } from 'src/app/core';
import { AngularFireAuth } from '@angular/fire/auth';
import { AngularFirestore } from '@angular/fire/firestore';
import { LogService } from 'src/app/shared/logger/log.service';
import { LogPublishersService } from 'src/app/shared/logger/log-publishers.service';
import { HttpClient, HttpHandler } from '@angular/common/http';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

fdescribe('UserLoginContentComponent', () => {
  let component: UserLoginContentComponent;
  let fixture: ComponentFixture<UserLoginContentComponent>;
  
  beforeAll(function(){
      TestBed.configureTestingModule({
        imports: [
          SharedModule,
          AngularFireModule.initializeApp(environment.firebase),
          RouterTestingModule,
          BrowserAnimationsModule
        ],
        declarations: [UserLoginContentComponent],
        providers: [ 
          AuthService,
          AngularFireAuth,
          AngularFirestore,
          LogService,
          LogPublishersService,
          HttpClient,
          HttpHandler
        ]
      }).compileComponents();

      fixture = TestBed.createComponent(UserLoginContentComponent);
      component = fixture.componentInstance;
      fixture.detectChanges();

    });
    
});

以及如何测试这个组件?

我正在使用以下测试:

it('COrrect login',(async(done) => {
    component.loginModel.email = 'correctemail@gmail.com';
    component.loginModel.password = 'correctpassword';

    await component.onSubmitTest().then((x) => {
      expect(x).toBe('login OK');
    });
    done();
  }));
  
  it('Wrong login (email)',(async(done) => {
    component.loginModel.email = 'wrongemail@gmail.com';
    component.loginModel.password = 'correctpassword';

    await component.onSubmitTest().then(() => {})
    .catch((err) => {
      expect(err).toBe('login Fail');
    })
    done();
  }));

我的课如下:

onSubmitTest() {
    return new Promise((res,rej) => {
      this.authService.emailPasswordLoginAsPromise(this.loginModel).then(() => {
        res('login OK')
      }).catch(e => {
        rej('login Fail')
      });
    })
  }

和我的 authService:

emailPasswordLoginAsPromise(login) {

    return new Promise((resolveEPL, rejectEPL) => {

      this.angularFireAuth.auth.signInWithEmailAndPassword(login.email, login.password)
        .then(credential => {
          resolveEPL(credential.user);
        }).catch(e => {
          rejectEPL(e);
        });
    });
  }

现在我所有的测试都使用带有 firebase 方法的异步方法

关于javascript - 如何在 jasmine 中测试一个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55121203/

相关文章:

javascript - Bootstrap 4 关闭模式,背景不会消失

javascript - 网站加载后如何触发按键组合?

javascript - InnerHTML 在 IE 中不起作用

css - 如何从底部强制 Angular Material 2 sidenav 内容

testing - Rails 3,测试方法太多?

r - 手动检查 R 中的面板单位根测试

javascript - Firefox 15 中的 ajaking onbeforeunload

Angular 4 - Http 到 HttpClient - 对象类型上不存在属性 'someproperty'

javascript - Angular2 - Loopback-sdk-builder - 如何在 api 调用中设置 header

java - 如何仅运行修改后的测试?