单元测试 – Angular 2(Mock Ionic2) – 没有App的提供者
我正在尝试为我的应用程序创建一个spec.ts.可悲的是,这是使用离子角度的
LoadingController.现在,当我尝试配置模块时,我需要为它提供LoadingController(因为它在模块的构造函数中).
我目前遇到的问题是LoadingController想要提供App对象/实例. (_app:App params) 我很绝望,所以我自己问了Ionic. github #8539 但是他们关闭了我的问题,因为这是一个问题,而不是一个问题,尽管我遇到了一些他们没有回应的问题.如果这是不可能的/没有人知道如何,这将是一个耻辱,因为它是一个非常酷的功能,它不仅影响LoadingController,f.e. AlertController和ToastController也受此影响. 我的testbed配置atm: TestBed.configureTestingModule({ declarations: [EventsPage],schemas: [CUSTOM_ELEMENTS_SCHEMA],providers: [ {provide: APICaller,useValue: mockAPICaller},{provide: NavController,useValue: mockNavController },{provide: LoadingController,useValue: ???????},//it seems like everything I try to enter here fails. ],imports: [FormsModule] }); 和EventsPage构造函数: constructor(public apiCaller: APICaller,public navCtrl: NavController,public loadingCtrl: LoadingController){} 编辑:LoadingController的用法 getEvents() { // setup a loadingscreen let loading = this.loadingCtrl.create({ content: "Loading..." }); // present the loadingscreen loading.present(); // reset the noEvents boolean. this.noEvents = true; // call the api and get all events this.apiCaller.getEvents() .subscribe(response => { // response is list of events this.events = response; // if the event is not empty,set noEvents to false. if (this.events.length > 0) { this.noEvents = false; } // close the loading message. loading.dismiss(); }); } 然后将导致此loadingspinner(具有不同的文本) 解决方法
有了这种类型的东西,你可能不想在UI中测试任何东西(关于使用LoadingController).您应该测试的是组件的行为.因此,当您为LoadingController创建模拟时,您想要做的是监视关键方法,并且您的期望应该测试以确保您正在调用LoadingController上的方法.这样做可以编写类似的测试
expect(loadingController.someMethod).toHaveBeenCalled(); // or expect(loadingController.someMethod).toHaveBeenCalledWith(args); 你的模拟不必遵循被模拟的项目的实际结构.例如,LoadingController.create返回一个Loading对象.在你的模拟中,你不需要这个.如果你想要,你可以在调用create时返回mock本身,而在mock中只需要有Loading的方法. 请记住,您只是在测试控制器的行为.模拟LoadingController实际上做了什么并不重要,只是你能够调用方法,并检查测试以确保它们在被调用时被调用.除此之外,你应该假设真正的LoadingController工作. 所以你可以有类似的东西 let mockLoadingController = { // Tried `create: jasmine.createSpy('create').and.returnValue(this) // seem this doesn't work. We just create the spy later create: (args: any) => { return this; },present: jasmine.createSpy('present'),dismiss: jasmine.createSpy('dismiss') }; spyOn(mockLoadingController,'create').and.returnValue(mockLoadingController); { provide: LoadingController,useValue: mockLoadingController } 然后在你测试中你可以做类似的事情 it('should create loader with args ...',() => { ... expect(mockLoadingController.create).toHaveBeenCalledWith({...}) }) it('should present the loader',() => { ... expect(mockLoadingController.present).toHaveBeenCalled(); }) it('should dismiss the loader when the api call returns',async(() => { .. expect(mockLoadingController.dismiss).toHaveBeenCalled(); })) 这是我现在用来测试的 class LoadingController { create(args: any) { return this; } present() {} dismiss() {} } @Component({ template: '' }) class TestComponent { constructor(private loadingController: LoadingController) {} setEvents() { let loading = this.loadingController.create({hello: 'world'}); loading.present(); loading.dismiss(); } } describe('component: TestComponent',() => { let mockLoadingController; beforeEach(async(() => { mockLoadingController = { create: (args: any) => { return this; },dismiss: jasmine.createSpy('dismiss') }; spyOn(mockLoadingController,'create').and.returnValue(mockLoadingController); TestBed.configureTestingModule({ declarations: [TestComponent],providers: [ { provide: LoadingController,useValue: mockLoadingController } ] }); })); it('should calling loading controller',() => { let comp = TestBed.createComponent(TestComponent).componentInstance; comp.setEvents(); expect(mockLoadingController.create).toHaveBeenCalledWith({ hello: 'world'}); expect(mockLoadingController.present).toHaveBeenCalled(); expect(mockLoadingController.dismiss).toHaveBeenCalled(); }); }); 也可以看看: > Jasmine docs on Spies (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |