0

I run my unit testing and I got Error: "StatusBar" plugin is not implemented on web

Currently this is from my app.component.ts

loadTheme =  (theme) => {   
if(this.platform.is('capacitor')) {       
   if (theme.theme_style.split(';')[2] == 'light') {
      console.log(StatusBar);
      StatusBar.setStyle({
        style: Style.Dark
      });
   } else {
      StatusBar.setStyle({
        style: Style.Light
      });
   }
 }
}

This is my app.component.specs.ts

describe ('Testing on loadTheme', () =>{
    beforeEach(() => {
     let imports:Array<any>=[
         BrowserModule,
         BrowserAnimationsModule,
         CommonModule,
         HttpClientTestingModule,
         SharedModule.forRoot(),
         RouterTestingModule,
         IonicModule.forRoot({}),
         TranslateModule.forRoot(),
       ];
       let providers:Array<any>=[
         provideMockStore({
           initialState:(props.initialState)? props.initialState:reducers
         }),
         {
           provide:Storage,
           useClass:MockStorage
         },
         {
           provide:StoreModule,
           useClass:MockStore
         },
         {
           provide:StatusBar,
           useValue:mockStatusBar
         },
       ];
       let config:TestModuleMetadata={
         declarations,
         imports,
         schemas: [CUSTOM_ELEMENTS_SCHEMA],
         providers
       };
       TestBed.configureTestingModule(config).compileComponents();
       fixture = TestBed.createComponent(props.mainComponent);
       component = fixture.componentInstance;
   });
   it('Should load current theme and set',async () => {         
       spyOn(component.platform,"is").and.returnValue(true);
       component.loadTheme(theme);
       expect(StatusBar.setStyle).toHaveBeenCalled();
  });
});

My mockStatusBar

export const mockStatusBar={   
   setBackgroundColor:jasmine.createSpy(),
   setStatusBarStyle:jasmine.createSpy(),
   setStyle:jasmine.createSpy() }

It seems like my mockStatusBar is not mocking the actual StatusBar

I am using

  • ionic 7
  • angular 16
  • capacitor 5

I want to mock the Ionic Capacitor StatusBar, so that I am able to test expect(StatusBar.setStyle).toHaveBeenCalled();

MensinBM
  • 1
  • 1

1 Answers1

0

Here is the solution, that worked for me: Capacitor: v4.7.1

Step 1: Update your "tsconfig.spec.json"

 "compilerOptions": {
"outDir": "./out-tsc/spec",
"types": [
  "jasmine"
]
],
"paths" : {
  "@capacitor/*": ["__mocks__/@capacitor/*"],
  "capacitor-plugin-shared-uuid": ["__mocks__/capacitor-plugin-shared-uuid"],
  "~*": ["node_modules/*"]
}},

Step 2: Add status bar dependency to the Package.json

 "@capacitor/status-bar": "4.1.1",

Step 3: Create mock directory inside your project folder

__mocks__/@capacitor/status-bar.ts

Add the following content inside your mock "status-bar.ts"

    import { AnimationOptions, BackgroundColorOptions, SetOverlaysWebViewOptions, StatusBarInfo, Style, StyleOptions } from '~@capacitor/status-bar';
export { Style } from '~@capacitor/status-bar';

// eslint-disable-next-line @typescript-eslint/naming-convention
export const StatusBar = {
  // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
  getInfo(): Promise<StatusBarInfo> {
    return Promise.resolve({ visible: true, style: Style.Default });
  },
  // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
  hide(options?: AnimationOptions): Promise<void> {
    return Promise.resolve(undefined);
  },
  // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
  setBackgroundColor(options: BackgroundColorOptions): Promise<void> {
    return Promise.resolve(undefined);
  },
  // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
  setOverlaysWebView(options: SetOverlaysWebViewOptions): Promise<void> {
    return Promise.resolve(undefined);
  },
  // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
  setStyle(options: StyleOptions): Promise<void> {
    return Promise.resolve(undefined);
  },
  // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
  show(options?: AnimationOptions): Promise<void> {
    return Promise.resolve(undefined);
  },
};

Step 4: Add the following code to the app.state.spec.ts file for unit testing

import { StatusBar, Style } from '@capacitor/status-bar';

 let statusBarSpy;

describe('handleModalWillOpen', () => {
        it('should open modal with dark statusbar', async () => {
            await itShouldSetStatusBarStyle(Style.Dark);
        });
        it('should open modal with light statusbar', async () => {
            await itShouldSetStatusBarStyle(Style.Light);
        });

        async function itShouldSetStatusBarStyle(style: Style) {
      spyOn(StatusBar, 'setStyle');
      await store.dispatch(new ModalWillOpen({ statusBarStyle: style })).toPromise();
      expect(StatusBar.setStyle).toHaveBeenCalledTimes(1);
      expect(StatusBar.setStyle).toHaveBeenCalledWith(objectContaining({ style }));
      expect(store.snapshot().app?.visibleModalComponentProperties).toEqual([{ statusBarStyle: style }]);
        };
    });

Hope this helps you and if so. Pl give a thumbs up :-)

Thanks.

  • Thanks Kumar for your help, I did the steps but still not working, it was working previously at capacitor 4. I event console.log at setStyle(options: StyleOptions), its not firing the test folder. Seems it is ignoring tsconfig.specs.json – MensinBM Jul 31 '23 at 01:22