#StackBounty: #angular #unit-testing Test AngularFireAuth Wrapper, without using AngularFireAuth mock

Bounty: 400

I would like to have a AuthWrapper Service that wraps the AngularFireAuth Service. Something like this.

@Injectable({
  providedIn: 'root'
})
export class AuthWrapper {
  constructor(public afAuth: AngularFireAuth) { }

  isAuthenticated(): Observable<firebase.User> {
    return this.afAuth.user;
  }

  createUserWithEmailAndPassword(email: string, password: string): Promise<String> {
    let authPromise: Promise<firebase.auth.UserCredential> =
      this.afAuth.auth.createUserWithEmailAndPassword(email, password);
    return authPromise
      .then((value) => {
        return value.user.email;
      })
      .catch(function(error) {
        return error.message;
      });
  }
}

I want a wrapper, so that I can test my connection to AngularFireAuth. Other tests mock the AuthWrapper.

( Reason for not mocking AngularFireAuth: Say I mock AngularFireAuth, then I am determining the mock’s return values. Then I am saying that I understand what these values would look like. It is not safe to assume this without ever testing these by calling the backend. Say google changes how the results of the real AngularFireAuth’s methods, I would then be forced to change the results of each of my AngularFireAuth mocks. Instead it is better to wrap AngularFireAuth in a wrapper, and just change that wrapper’s methods to conform to google’s changes. )

My tests in Karmine and Jasmine result in an “Async callback was not invoked within 5000ms error.” I know the user is signed it because the first expect passes, but how do I get the second expect to work?:

describe('AuthWrapperService', () => {
  let fireAuthService: AngularFireAuth;
  let password = "dcbA4321!";

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        AngularFireModule.initializeApp(environment.firebase),
        AngularFireModule,
        AngularFireAuthModule
      ],
      providers: [AngularFireAuth, AuthWrapperService],
      declarations: []
    })
    fireAuthService = TestBed.get(AngularFireAuth);
  });

  it('should sign in user', async() => {
    const email = "anyemail@gmail.com";
    let authWrap = new AuthWrapperService(fireAuthService);
    let userEmail = await authWrap.createUserWithEmailAndPassword(email, password);
    expect(userEmail).toBe("anyemail@gmail.com");
    let obs = authWrap.isAuthenticated();
    let promise = obs.toPromise();
    let user = await promise.then((result) => {return result});
    expect(user.email).toBe("anyemail@gmail.com");
  });
});  

I haven’t seen any Angular testing code, where the AngularFireAuth isn’t mocked.


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.