Angular2 / Jasmine:间谍单元测试方法没有看到被调用的方法

时间:2017-07-04 14:32:23

标签: angular unit-testing testing jasmine karma-runner

我在检测间谍时遇到了调用函数的问题。它是服务的单元测试。 我已经尝试了两种不同的方法,使用TestBed.get方法(在#39;它应该仅检查状态')并监视注入的虚拟类("在其中应该登录未知的Facebook&#34 ;),但他们似乎都没有工作 我已经做了一些打印,看看是否使用了方法,并且显示了。 这是一个spec文件:

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

import {FacebookServiceMock } from './../test-helpers/facebook-service-mock';
import { SocialsServiceDummy } from './../test-helpers/socialsServiceDummy';
import { ErrorDouble } from './../test-helpers/errorDouble';

import { ErrorsService } from './../../app/services/errors.service';
import { social_config, SocialConfig, SOCIAL_CONFIG } from './../../app/socials/social-config';
import { SocialsService } from './../../app/services/socials.service';
import { FacebookLoginService } from './../../app/services/facebook-login.service';
import { FacebookService } from 'ngx-facebook';

describe('Facebook-login-service test', () => {
    let socialsServiceSpy: any;

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            providers: [
                FacebookLoginService,
                { provide: FacebookService, useFactory: () => { return new FacebookServiceMock() }},
                { provide: SocialsService, useFactory: () => {  return new SocialsServiceDummy() }},
                { provide: ErrorsService, useFactory: () => { return new ErrorDouble() } },
                { provide: social_config, useValue: SOCIAL_CONFIG }
            ]
        });


    });

    beforeEach(() => {
        socialsServiceSpy = TestBed.get(SocialsService);
        spyOn(socialsServiceSpy, 'updateAccount');

    });

    afterEach(()=>{
        TestBed.resetTestingModule();

    });

    it('should login unknown to facebook',
        async(inject([FacebookLoginService, FacebookService, SocialsService, ErrorsService, social_config], (facebookLoginService, FacebookServiceMock, SocialsServiceDummy, ErrorDouble, SOCIAL_CONFIG) => {
                let mockReturn = {
                    status: "unknown",
                    authResponse: {
                        userID: '123456',
                        accessToken: 'token',
                        expiresIn: 3600
                    }
                };

                spyOn(FacebookServiceMock, 'getLoginStatus').and.returnValue(Promise.resolve(mockReturn));
                spyOn(SocialsServiceDummy, 'addNewSocialAccount').and.callThrough();
                spyOn(facebookLoginService, 'loginToFacebook').and.callThrough();

                facebookLoginService.checkLoginStatus();
                expect(facebookLoginService.loginToFacebook).toHaveBeenCalled();
                expect(SocialsServiceDummy.addNewSocialAccount).toHaveBeenCalledWith('facebook', mockReturn.authResponse.userID, mockReturn.authResponse.accessToken, mockReturn.authResponse.expiresIn);
            })
        ));

    it('should check only status',
        async(inject([FacebookLoginService, FacebookService, SocialsService, ErrorsService, social_config], (facebookLoginService, FacebookServiceMock, SocialsServiceDummy, ErrorDouble, SOCIAL_CONFIG) => {
                let mockReturn = {
                    status: "connected",
                    authResponse: {
                        userID: '123456',
                        accessToken: 'token',
                        expiresIn: 3600
                    }
                };
                spyOn(FacebookServiceMock, 'getLoginStatus').and.returnValue(Promise.resolve(mockReturn));
               // spyOn(SocialsServiceDummy, 'updateAccount').and.callThrough();

                facebookLoginService.checkLoginStatus();
                expect(socialsServiceSpy.updateAccount).toHaveBeenCalledWith('facebook', mockReturn.authResponse.userID, mockReturn.authResponse.accessToken, mockReturn.authResponse.expiresIn);


            })
        ));
});

FacebookLoginService如下所示:

/**
 * Created by Daniel on 2017-06-19.
 */
import { Injectable, Inject } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { FacebookService, LoginResponse, LoginOptions } from 'ngx-facebook';
import { ErrorsService } from './errors.service';
import { social_config, SocialConfig } from './../socials/social-config';
import { NewSocialAccount } from './../shared/models/new-social-account';
import { SocialsService } from "./socials.service";

@Injectable()

export class FacebookLoginService {
    private loginOptions : LoginOptions = {
        scope: this.socialConfig.facebook.scope
    }

    private attemptToLogin =  new Subject<boolean>()
    private newSocialAccount =  new Subject<any>();

    login$ = this.attemptToLogin.asObservable();
    newSocial$ = this.newSocialAccount.asObservable();

    constructor(
        private facebookService: FacebookService,
        private socialsService: SocialsService,
        private errorsService: ErrorsService,
        @Inject(social_config) private socialConfig: SocialConfig
    ) {}

    initSocials() : void {
        this.facebookService.init({appId: this.socialConfig.facebook.appId, version: this.socialConfig.facebook.version});
    }

    checkLoginStatus() : void{
        this.facebookService.getLoginStatus().then(
            (res) => {
                if(res.status == "connected") {
                    const updatedAccount = this.createNewAccountObject('facebook', res.authResponse.userID, res.authResponse.accessToken, res.authResponse.expiresIn);
                    this.socialsService.updateAccount(updatedAccount).then(
                        () => {
                            this.attemptToLogin.next(true);
                        },
                        error => {
                            this.errorsService.startErrorAction(error);
                        }
                    )
                } else {
                   this.loginToFacebook();
                }
            },
            error => {
                alert('Unable to connect with Facebook. Please try later');
            }
        )
    }

    loginToFacebook() : void {
        this.facebookService.login(this.loginOptions).then(
            (res: LoginResponse) => {
                const newAccount = this.createNewAccountObject('facebook', res.authResponse.userID, res.authResponse.accessToken, res.authResponse.expiresIn);
                this.socialsService.addNewSocialAccount(newAccount).then(
                    (res) => {
                        this.confirmLoginNewSocialAccount(res, 'facebook');
                    },
                    error => {
                        this.errorsService.startErrorAction(error);
                    }
                )
            },
            error => {
                alert('Unable to connect with Facebook. Please try later');
            }
        )

    }

    logout(): void {
        this.facebookService.logout();
    }

    private createNewAccountObject(socialStr: string, userStr: string, tokenStr: string, expiresNr: number): NewSocialAccount {
            return {
                social: socialStr,
                userID: userStr,
                token: tokenStr,
                expires:  expiresNr
            };
        }

    private confirmLoginNewSocialAccount(response: any, accountType: string) {
        this.newSocialAccount.next({login: response.login, social: accountType});

    }
}

这是来自注入社会服务的虚拟文件

import { SocialAccount} from './../../app/shared/models/social-account';
import { NewSocialAccount} from './../../app/shared/models/new-social-account';

export class SocialsServiceDummy {

    getSocials(): Promise<SocialAccount[]> {
      let socials =  [

      ];
      return Promise.resolve(socials);
    }

    addNewSocialAccount(newAccount: NewSocialAccount) : Promise<any>{
      let social4 = {login: 'facebook', userId: '1fsdf42343', token: 'some_token', expire: 3600};
      return Promise.resolve(social4);
    }

    deleteAccount(id: number): Promise<void> {
      return Promise.resolve(null);
    }

    updateAccount(account: SocialAccount ):  Promise<void>{
        return Promise.resolve(null);
    }

}

我已经从FacebookServiceMock辞职并仅将其用作注入的存根,并从间谍返回结果。 错误double和social_config也是存根。

我很高兴能帮到我做错了什么

干杯。

1 个答案:

答案 0 :(得分:0)

我使用spyOn不同。也许这有效:

let spy = spyOn(new Date(), 'toString');
expect(spy.calls.count()>0).toBeTruthy();