cancel
Showing results for 
Search instead for 
Did you mean: 

Using SAP CAP typescript ApplicationService in Jest on cds 7

jorgegrau
Explorer
0 Kudos

Hi everyone!

First of all, I appreciate your time reading this.

We have a Typescript CAP project working fine since a lot of time (CDS 5) and since we upgrade to CDS 7 we're having problems on Jest testing. Basically our ApplicationService isn't loading on Jest testing and then non of our Handlers is loaded making all our test fail.

Making some changes to our code we see that if we change our XXService.ts to XXXService.js all work fine like before. As comment before, if we run it with CDS 6 all works fine.

Our current version of CDS is 7.3 and also try it with CDS 7.4 with the same result.

Have been change anything on CDS 7 and Jest? Is there anything we can do?

Thanks and regards,

Edit: Adding an extra information for more detail:

srv/service/TestService.cds

service TestService { function hello(to : String) returns String;};

srv/service/TestService.ts

import cds from '@sap/cds';
export class TestService extends cds.ApplicationService {
async init() { console.log("Hello world!"); await super.init(); }}
module.exports.TestService = TestService;

srv/server.ts

import cds from '@sap/cds';import helmet from 'helmet';import { Application } from 'express';
cds.on('bootstrap', (app: Application) => { app.use(helmet());});
module.exports = (o): Function => { return cds.server(o);};

srv/index.cds

using from './services/TestService';

jest.config.ts

import type { Config } from 'jest';
export default async (): Promise<Config> => { return { preset: 'ts-jest', testEnvironment: 'node', transform: { '\\.js?$': 'babel-jest', '\\.ts$': 'ts-jest', }, testMatch: ['**/*.test.ts'], verbose: false, roots: ['test'], maxWorkers: 1, logHeapUsage: true, setupFilesAfterEnv: ['./jest.setup.ts'], globalSetup: './jest.global.setup.ts', };};

jest.global.setup.ts

import cds from '@sap/cds';
export default async (): Promise<void> => { console.log("I'll be called first before any test cases run"); // load Axios const service = cds.test(__dirname); await service; globalThis.__service__ = service; globalThis.__cds__ = cds; console.log('end global setup');};

npm run test console oput:

> captest@1.0.0 test<br>> jest<br>Determining test suites to run...I'll be called first before any test cases run<br>[cds] - loaded model from 4 file(s):<br>  srv/index.cds<br>  srv/services/TestService.cds<br>  db/TestModel.cds<br>  node_modules/@sap/cds/common.cds<br>[cds] - connect to db > sqlite { url: 'db.sqlite' }<br>[cds] - using authentication: { kind: 'mocked' } <br>[auth] - WARNING: <br>    Usage of 'ID' in user configurations is deprecated and won't be<br>    supported in future releases. → Please use property 'id' instead.<br>  <br>[cds] - serving TestService { path: '/odata/v4/test' }<br>[cds] - server listening on { url: 'http://localhost:54878' }<br>[cds] - launched at 1/15/2024, 1:22:14 PM, version: 7.3.0, in: 307.46ms<br>[cds] - [ terminate with ^C ]<br>end global setup<br> PASS  test/Example.test.ts (261 MB heap size)<br>[odata] - GET /odata/v4/test/$metadata <br>Test Suites: 1 passed, 1 total<br>Tests:       1 passed, 1 total<br>Snapshots:   0 total<br>Time:        0.115 s, estimated 1 s<br>Ran all test suites.

We can see that Hello World isn't logged on console. Now change our handler to js:

TestService.js

const cds = require('@sap/cds');
module.exports = () => { console.log("Hello world!");}

If we re-run our tests:

npm run test<br>> captest@1.0.0 test<br>> jest<br>Determining test suites to run...I'll be called first before any test cases run<br>[cds] - loaded model from 4 file(s):<br>  srv/index.cds<br>  srv/services/TestService.cds<br>  db/TestModel.cds<br>  node_modules/@sap/cds/common.cds<br>[cds] - connect to db > sqlite { url: 'db.sqlite' }<br><strong>Hello world!<br></strong>[cds] - using authentication: { kind: 'mocked' } <br>[auth] - WARNING: <br>    Usage of 'ID' in user configurations is deprecated and won't be<br>    supported in future releases. → Please use property 'id' instead.<br>  <br>[cds] - serving TestService { path: '/odata/v4/test', impl: 'srv/services/TestService.js' }<br>[cds] - server listening on { url: 'http://localhost:54907' }<br>[cds] - launched at 1/15/2024, 1:24:47 PM, version: 7.3.0, in: 328.202ms<br>[cds] - [ terminate with ^C ]<br>end global setup<br> PASS  test/Example.test.ts (262 MB heap size)<br>[odata] - GET /odata/v4/test/$metadata <br>Test Suites: 1 passed, 1 total<br>Tests:       1 passed, 1 total<br>Snapshots:   0 total<br>Time:        0.108 s, estimated 1 s<br>Ran all test suites.
As you can see now we have the "Hello World!" output on console because the Handler has been loaded.
View Entire Topic
Dinu
Contributor
0 Kudos

Have you setup preset and the environment variable CDS_TYPESCRIPT as described in documentation?

jorgegrau
Explorer
0 Kudos

Hi dinu.pavithran.1,

Yes, It is working fine with Typescript. It only doesn't load the Handler configruation.

I edit the post for more detail.

Thank you very much and regards,

Dinu
Contributor
0 Kudos

Plese check the documentation at the link provided. That setup works with cap v7. I don't know how the setup was with cap v5. I don't see the files mentioned in the documentation in what you mention in the question.