Error in Theia tests

I am trying to run a test-case similar to the examples/api-tests but I am getting following error.

● Test suite failed to run

The configuration is not set. Did you call FrontendApplicationConfigProvider#set?

> 1 | import {CommonCommands, ReactWidget} from '@theia/core/lib/browser';
    | ^
  2 | import {CommandRegistry} from '@theia/core/lib/common/command';
  3 | import {Message} from '@theia/core/shared/@phosphor/messaging';
  4 | import {inject, injectable, postConstruct} from '@theia/core/shared/inversify';

  at Function.get (../node_modules/@theia/core/src/browser/frontend-application-config-provider.ts:26:19)
  at Object.<anonymous> (../node_modules/@theia/core/src/browser/core-preferences.ts:103:56)
  at Object.<anonymous> (../node_modules/@theia/core/src/browser/shell/theia-dock-panel.ts:22:1)
  at Object.<anonymous> (../node_modules/@theia/core/src/browser/shell/application-shell.ts:30:1)
  at Object.<anonymous> (../node_modules/@theia/core/src/browser/shell/index.ts:17:1)
  at Object.<anonymous> (../node_modules/@theia/core/src/browser/index.ts:17:1)
  at Object.<anonymous> (src/browser/views/analysis-table/analysis-results-view-widget.tsx:1:1)
  at Object.<anonymous> (src/browser/__tests__/analysis-view.test.ts:8:1)

See my test case here

import 'reflect-metadata';
import { MessageService } from '@theia/core';
import { ContainerModule, Container } from '@theia/core/shared/inversify';
import { render } from '@testing-library/react'
import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
import { ApplicationProps } from '@theia/application-package/lib/application-props';

import { AnalysisResultsView } from '../views/analysis-table/analysis-results-view-widget';

describe('AnalysisResultsView', () => {

let widget: AnalysisResultsView;

beforeEach(async () => {
    FrontendApplicationConfigProvider.set({
        ...ApplicationProps.DEFAULT.frontend.config
    });
    const module = new ContainerModule( bind => {
        bind(MessageService).toConstantValue({
            info(message: string): void {
                console.log(message);
            }
        } as MessageService);
        bind(AnalysisResultsView).toSelf();
    });
    const container = new Container();
    container.load(module);
    widget = container.resolve<AnalysisResultsView>(AnalysisResultsView);
});

it('should render Analysis view correctly', async () => {
    const element = render(widget.render());
    expect(element.queryByText('Analysis Results')).toBeTruthy();
});

});

Any help would be appreciated , thanks ,
Abhishek

Hi @chakraborty-slx,

So what happens in here is that although you set the FrontentApplicationConfig, it happens too late. If you look at the exception stack, you’ll see that it already starts at line 8 in your test file, when you import your AnalysisResultView. In a longer line of dependencies this file depends on core-preferences.ts which requires the config already when being imported. That’s the source of the exception.

Now to fix this, you simply need to move the FrontendApplicationConfigProvider.set call to the line directly after importing the ApplicationProps but before importing AnalysisResultsView. See for an example the following test file which does this at the start of the file:

Thanks @msujew for your reply, I also tried that , but there is another error about it.

   lerna ERR! FAIL src/browser/__tests__/analysis-view.test.ts
lerna ERR!   ● Test suite failed to run
lerna ERR! 
lerna ERR!     Jest encountered an unexpected token
lerna ERR! 
lerna ERR!     This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
lerna ERR! 
lerna ERR!     By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
lerna ERR! 
lerna ERR!     Here's what you can do:
lerna ERR!      • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
lerna ERR!      • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
lerna ERR!      • If you need a custom transformation specify a "transform" option in your config.
lerna ERR!      • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
lerna ERR! 
lerna ERR!     You'll find more details and examples of these config options in the docs:
lerna ERR!     https://jestjs.io/docs/en/configuration.html
lerna ERR! 
lerna ERR!     Details:
lerna ERR! 
lerna ERR!    /theia-ide/node_modules/@theia/core/src/browser/style/variables-dark.useable.css:20
lerna ERR!     :root {
lerna ERR!     ^
lerna ERR! 
lerna ERR!     SyntaxError: Unexpected token ':'
lerna ERR! 
lerna ERR!       at Runtime.createScriptFromCode (../node_modules/jest-runtime/build/index.js:1350:14)
lerna ERR!       at Object.<anonymous> (../node_modules/@theia/core/src/browser/theming.ts:151:31)

my jest.config.ts

import type { Config } from '@jest/types';

export default async (): Promise<Config.InitialOptions> => ({

    preset: 'ts-jest',

    testMatch: ['**.test.ts'],

    rootDir: '../',

    transform: {

        '^.+\\.(ts)$': 'ts-jest',

    }

});

and tsconfig.json

{

  "compilerOptions": {

    "skipLibCheck": true,

    "declaration": true,

    "declarationMap": true,

    "noImplicitAny": true,

    "noEmitOnError": false,

    "noImplicitThis": true,

    "noUnusedLocals": true,

    "strictNullChecks": true,

    "experimentalDecorators": true,

    "emitDecoratorMetadata": true,

    "downlevelIteration": true,

    "resolveJsonModule": true,

    "module": "commonjs",

    "moduleResolution": "node",

    "target": "ES2017",

    "jsx": "react",

    "lib": [

      "ES2017",

       "dom"

      ],

    "sourceMap": true,

    "rootDir": "src",

    "outDir": "lib"

  },

  "include": [

    "src"

  ]

}

You will need to add an appropriate jest transformer to be able to debug files which import css files. Something similar to this github comment should work.

Thanks again @msujew , but my problem is still there, looks like i am using a different approach that the theia-ide examples where i see difference in the way scripts are running for test

THEIA_IDE
“test”: “yarn rebuild && theia test . --plugins=local-dir:…/…/plugins --test-spec=…/api-tests/**/*.spec.js”,

in my case
“test”: “jest --config ./configs/jest.config.ts”

import type { Config } from '@jest/types';

export default async (): Promise<Config.InitialOptions> => ({

    preset: 'ts-jest',

    testMatch: ['**/__tests__/**/**.test.ts'],

    rootDir: '../',

    transform:{

        '^.+\\.(ts)$': 'ts-jest',

        "^.+\\.css$": "jest-transform-css",

    }

});

Here is a repo to reproduce the problem theia-examples/theia-widget at master · chakraborty-slx/theia-examples (github.com)

@chakraborty-slx the following official documentation from jest should help you, it fixed the problem for me:

You’ll then need to fix the tests of course which aren’t passing.

 $ yarn test
yarn run v1.22.4
warning package.json: No license field
$ jest --config configs/jest.config.ts
 FAIL  src/browser/theia-widget-widget.test.ts
  TheiaWidgetWidget
    ✕ should render react node correctly (16 ms)
    ✕ should inject 'MessageService' (2 ms)

  ● TheiaWidgetWidget › should render react node correctly

    No matching bindings found for serviceIdentifier: EditorManager

      26 |         const container = new Container();
      27 |         container.load(module);
    > 28 |         widget = container.resolve<TheiaWidgetWidget>(TheiaWidgetWidget);
         |                            ^
      29 |     });
      30 |
      31 |     it('should render react node correctly', async () => {

      at _validateActiveBindingCount (../node_modules/inversify/src/planning/planner.ts:113:23)
      at _getActiveBindings (../node_modules/inversify/src/planning/planner.ts:91:5)
      at _createSubRequests (../node_modules/inversify/src/planning/planner.ts:163:26)
      at ../node_modules/inversify/src/planning/planner.ts:197:17
          at Array.forEach (<anonymous>)
      at ../node_modules/inversify/src/planning/planner.ts:196:26
          at Array.forEach (<anonymous>)
      at _createSubRequests (../node_modules/inversify/src/planning/planner.ts:167:20)
      at Object.plan (../node_modules/inversify/src/planning/planner.ts:243:9)
      at ../node_modules/inversify/src/container/container.ts:367:27
      at Container.Object.<anonymous>.Container._get (../node_modules/inversify/src/container/container.ts:354:47)
      at Container.Object.<anonymous>.Container.get (../node_modules/inversify/src/container/container.ts:246:21)
      at Container.Object.<anonymous>.Container.resolve (../node_modules/inversify/src/container/container.ts:278:30)
      at Object.<anonymous> (src/browser/theia-widget-widget.test.ts:28:28)

  ● TheiaWidgetWidget › should render react node correctly

    TypeError: Cannot read property 'render' of undefined

      30 |
      31 |     it('should render react node correctly', async () => {
    > 32 |         const element = render(widget.render());
         |                                       ^
      33 |         expect(element.queryByText('Display Message')).toBeTruthy();
      34 |     });
      35 |

      at Object.<anonymous> (src/browser/theia-widget-widget.test.ts:32:39)

  ● TheiaWidgetWidget › should inject 'MessageService'

    No matching bindings found for serviceIdentifier: EditorManager

      26 |         const container = new Container();
      27 |         container.load(module);
    > 28 |         widget = container.resolve<TheiaWidgetWidget>(TheiaWidgetWidget);
         |                            ^
      29 |     });
      30 |
      31 |     it('should render react node correctly', async () => {

      at _validateActiveBindingCount (../node_modules/inversify/src/planning/planner.ts:113:23)
      at _getActiveBindings (../node_modules/inversify/src/planning/planner.ts:91:5)
      at _createSubRequests (../node_modules/inversify/src/planning/planner.ts:163:26)
      at ../node_modules/inversify/src/planning/planner.ts:197:17
          at Array.forEach (<anonymous>)
      at ../node_modules/inversify/src/planning/planner.ts:196:26
          at Array.forEach (<anonymous>)
      at _createSubRequests (../node_modules/inversify/src/planning/planner.ts:167:20)
      at Object.plan (../node_modules/inversify/src/planning/planner.ts:243:9)
      at ../node_modules/inversify/src/container/container.ts:367:27
      at Container.Object.<anonymous>.Container._get (../node_modules/inversify/src/container/container.ts:354:47)
      at Container.Object.<anonymous>.Container.get (../node_modules/inversify/src/container/container.ts:246:21)
      at Container.Object.<anonymous>.Container.resolve (../node_modules/inversify/src/container/container.ts:278:30)
      at Object.<anonymous> (src/browser/theia-widget-widget.test.ts:28:28)

  ● TheiaWidgetWidget › should inject 'MessageService'

    Cannot spyOn on a primitive value; undefined given

      35 |
      36 |     it('should inject \'MessageService\'', () => {
    > 37 |         const spy = jest.spyOn(widget as any, 'displayMessage')
         |                          ^
      38 |         widget['displayMessage']();
      39 |         expect(spy).toBeCalled();
      40 |     });

      at ModuleMockerClass.spyOn (../node_modules/jest-mock/build/index.js:783:13)
      at Object.<anonymous> (src/browser/theia-widget-widget.test.ts:37:26)

Test Suites: 1 failed, 1 total
Tests:       2 failed, 2 total
Snapshots:   0 total
Time:        3.609 s
Ran all test suites.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

thanks @vince-fugnitto this resolved my problem with the css resource, though I am still struggling to fix my test , in which i have to add all the bindings required only to resolve a single inject for EditorManager.

regards,
Abhishek

@chakraborty-slx that’s correct, you must be able to bind the necessary injections so your tests can properly test them, even if they are mocked.

ex problem-manager:

1 Like