首页 文章

离子茉莉花试验模拟提供者

提问于
浏览
1

我正在为登录页面创建单元测试(离子3角4 j) . 我的应用程序 Build 在ionic unit test example

我正在尝试模拟正在验证我的用户的提供程序 .

class UsersProviderMock {
    public login():any {
        console.warn("MOCK TEST")
    }
}

我的登录页面代码是:

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { DashboardPage } from '../dashboard/dashboard'
import { Platform } from 'ionic-angular';
import {UsersProvider} from '../../providers/users/users'

@IonicPage()
@Component({
  selector: 'page-login',
  templateUrl: 'login.html',
  providers:[UsersProvider]
})
export class LoginPage {

  email: string = "";
  password: string = "";

  constructor(public navCtrl: NavController,
    public navParams: NavParams,
    private platform: Platform,
  private userprovider:UsersProvider) { }

  ionViewDidLoad() {
  }

  login() {

    console.warn("LOGIN")    
    this.userprovider.login()

  }

}

我在单元测试中尝试实现的是测试提供者的登录方法是否被调用 .

我的单元测试看起来像:

describe('Login', () => {
    let inputs: DebugElement[];
    let comp: LoginPage;
    let fixture: ComponentFixture<LoginPage>;
    var mock;

    beforeEach(async(() => {

      TestBed.configureTestingModule({
        declarations: [LoginPage],
        imports: [
            HttpModule,
            IonicModule.forRoot(LoginPage)
        ],
        providers: [
            UsersProvider,
            { provide: Apollo, useClass: ApolloMock },
            NavController,
            { provide: ToastController, useClass: () => ToastControllerMock.instance() },
            { provide: LoadingController, useClass: () => LoadingControllerMock.instance() },
            { provide: NavParams, useClass: NavParamsMock },
            { provide: Platform, useClass: PlatformMock },
            { provide: StatusBar, useClass: StatusBarMock },
            { provide: SplashScreen, useClass: SplashScreenMock },
        ]
        }).overrideComponent(LoginPage, {
        set: {
            providers: [
                { provide: UsersProvider, useClass: UsersProviderMock }
            ]
        }
    })



        fixture = TestBed.createComponent(LoginPage);
        mock=TestBed.get(UsersProvider)
        comp = fixture.componentInstance;
    }))

    it('A Test',()=>{
        spyOn(mock,'login')
        comp.login()
        expect(mock.login).toHaveBeenCalled()
    })

});

我无法理解的是调用了我的mock类的login方法 . 我在控制台中有警告消息(WARN LOG:'MOCK TEST') .

但我的测试A测试失败并显示以下消息:

Expected spy test to have been called.

1 回答

  • 3

    控制台中的 MOCK TEST 表示未调用 Spy 而是调用原始 UsersProviderMock 方法 . 检测错误行为的更好方法是在不应该调用的方法中抛出错误:

    class UsersProviderMock {
        public login():any {
            throw new Error('should not be called');
        }
    }
    

    mock=TestBed.get(UsersProvider) 从根注入器获取提供程序实例,而组件从其自己的注入器获取实例 - 未注释 UsersProviderMock . mock 是除了测试本身以外的任何地方都未使用的提供程序实例 . 这种情况是可能的,因为 UsersProvider 被提供给测试床,而不需要:

    providers: [
            UsersProvider,
            ...
    

    窥探组件实例的一种方法是监视原型方法(如this answer中所述):

    spyOn(UsersProviderMock.prototype,'login')
        comp.login()
        expect(UsersProviderMock.prototype.login).toHaveBeenCalled()
    

    另一种方法是避免 UsersProviderMock 类,因为它在这里是多余的:

    set: {
            providers: [
                { provide: UsersProvider, useValue: jasmine.createSpyObj('users', ['login']) }
            ]
        }
    
        ...
        comp.login()
        expect(UsersProviderMock.prototype.login).toHaveBeenCalled()
    

相关问题