0

can anyone help me please? I'm trying to test a function that call a firebase functions, but when I call the main function and start to run a firebase functions, I got a error

err TypeError: Cannot read property 'emailPasswordLoginAsPromise' of null

i don't know what is happen, follow my code:

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

my Function that I'm calling:

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

in my authService, my emailloginasPromise is like that :

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

it's my first time with testing jasmine, I studied, but i don't know how I can solve this problem, how call a async func and getting the return.

4
  • Did you check if authService is provided inside constructor ? Commented Mar 12, 2019 at 14:18
  • @jakubm now i'm using the component = fixture.componentInstance;, and is working, that was the problem, no provider for authservice, but isn't working my async function, i call with it('', async((done) => { // do my promise ... but my test is executed first, and then my promise, how can i fix it? })) Commented Mar 12, 2019 at 17:57
  • Could you update your question and the code snippets it will be easier for me to see what's going on. Commented Mar 13, 2019 at 9:42
  • @jakubm I solved my problem, I posted my answer, thank u for all ! Commented Mar 13, 2019 at 12:19

1 Answer 1

1

i founded the problem, follow the fix:

The authService isn't provide when i'm creating a stance of my class, so now i'm using the component:

component = fixture.componentInstance;

with this component now I'm calling my method and all providers is working.

Follow my describe:

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

    });
    
});

and how to test this component?

I'm using the follow tests:

it('COrrect login',(async(done) => {
    component.loginModel.email = '[email protected]';
    component.loginModel.password = 'correctpassword';

    await component.onSubmitTest().then((x) => {
      expect(x).toBe('login OK');
    });
    done();
  }));
  
  it('Wrong login (email)',(async(done) => {
    component.loginModel.email = '[email protected]';
    component.loginModel.password = 'correctpassword';

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

My class follow:

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

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

And now all my testing is working with asynchronous method with firebase methods

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.