Unable to run unit tests in C8Y applications

I am trying to run tests on a web application I built with the C8Y CLI but I am running into a couple of problems.

I have organized my source code into two folders: app and test. The former stores all of my application code and the latter is reserved for executing unit tests on it.

src
 ├── app
       ├── live-dashboard
            ├── live-dashboard.component.html
            ├── live-dashboard.component.less
            ├── live-dashboard.component.ts
            ├── live-dashboard.factory.ts
            ├── live-dashboard.module.ts
            ├── live-dashboard.service.ts
 ├── test
      ├── live-dashboard.component.spec.ts

Here is my test file:

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '@angular/core';

import { LiveDashboardComponent} from 'src/app/live-dashboard/live-dashboard.component'
import { LiveDashboardService } from 'src/app/live-dashboard/live-dashboard.service';

describe('LiveDashboardComponent test', () => {
    let fixture: ComponentFixture<LiveDashboardComponent>;
    let component: LiveDashboardComponent;
    let service: LiveDashboardService

    // Init Angular Test Environment
    beforeAll(() => {
        TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamic())
    });

    // Configure Testing Module
    beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [
                LiveDashboardComponent
            ],
            providers: [
                LiveDashboardService
            ],
            schemas: [
                CUSTOM_ELEMENTS_SCHEMA,
                NO_ERRORS_SCHEMA
            ]
        }).compileComponents();  // necessary for when our components use templateUrl 
                                 // and styleUrls to load external files (css and html) 
                                 // that compiler has to read asynchronously.
    })

    // Configure component and service(s)
    beforeEach(() => {
        fixture = TestBed.createComponent(LiveDashboardComponent);
        component = fixture.componentInstance;
        fixture.detectChanges(); // component will start with ngOnInit
        service = fixture.debugElement.injector.get(LiveDashboardService);
    })

    test('Component should be defined', () => {
        expect(component).toBeDefined();
    })

    test.skip('Test the getModeFragmentSeries', () => {

    })

    afterEach(() => {
        fixture.destroy(); // Destroys the fixture and its contents
        component = null; // Resets the component reference
        fixture = null; // Resets the fixture reference
      });
});

When I try to run npm test, however, I keep getting an error stating that the test file cannot find the

 FAIL  src/app/live-dashboard/live-dashboard.component.spec.ts
  ● Test suite failed to run

    Cannot find module 'src/app/live-dashboard/live-dashboard.component' from 'src/app/live-dashboard/live-dashboard.component.spec.ts'

      4 | import { CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '@angular/core';      
      5 |
    > 6 | import { LiveDashboardComponent} from 'src/app/live-dashboard/live-dashboard.component'
        | ^
      7 | import { LiveDashboardService } from 'src/app/live-dashboard/live-dashboard.service';
      8 |
      9 | describe('LiveDashboardComponent test', () => {

      at Resolver._throwModNotFoundError (node_modules/jest-resolve/build/resolver.js:491:11)
      at Object.<anonymous> (src/app/live-dashboard/live-dashboard.component.spec.ts:6:1)

Test Suites: 2 failed, 2 total
Tests:       0 total
Snapshots:   0 total
Time:        5.933 s
Ran all test suites.

I have tried moving the test file to the app folder but I just got the same response.

In addition, I am getting another error, this time with my first test block stating that the property 'toBeDefined' does not exist on type 'Assertion'.ts(2339).

I hovered over the expect method and discovered that it is using the expect method from the Chai framework:
var expect: Chai.ExpectStatic (val: any, message?: string) => Chai.Assertion

How can this be if the project is already set up to use Jest as its testing framework? How would I get it to use Jest’s expect method instead?

Hi Lucas,

I guess you need to change your imports to relative paths. So instead of src/app/live-dashboard/live-dashboard.component use ../app/live-dashboard/live-dashboard.component.

Regarding the types:
Did you install @types/jest as a devDependency in you project?
Did you mention jest in the compilerOptions.types array of your tsconfig.spec.json ?

Regards,
Tristan

Hi Tristan,

I changed the relative imports to relative paths and that fixed the first issue.

On the other hand, I had checked the devDependency and the ts.config.spec.json file beforehand and they had the same configuration you mentioned.

package.json

"devDependencies": {
    "@angular-devkit/build-angular": "14.0.6",
    "@angular/compiler-cli": "14.0.6",
    "@angular/language-service": "14.0.6",
    "@angular/localize": "14.0.6",
    "@angular/service-worker": "14.0.6",
    "@c8y/cli": "1018.0.211",
    "@jest/types": "^29.6.3",
    "@types/jest": "^28.1.6",
    "ajv": "^7.2.4",
    "cypress": "^13.1.0",
    "jest-preset-angular": "^12.2.0",
    "typescript": "4.7.4"
  },

tsconfig.spec.json

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/spec",
    "types": ["jest"],
    "esModuleInterop": true
  },
  "include": ["src/**/*.spec.ts", "src/**/*.d.ts"]
}

Update: I properly configured my test file and the test runs without errors, even though the toBeDefined error still appears underlined in red.

This is what my final code looks like:

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '@angular/core';

import { LiveDashboardComponent} from '../../app/live-dashboard/live-dashboard.component'
import { LiveDashboardService } from '../../app/live-dashboard/live-dashboard.service';
import { FormBuilder } from '@angular/forms';
import { MeasurementService } from '@c8y/client';

describe('LiveDashboardComponent test', () => {
    let fixture: ComponentFixture<LiveDashboardComponent>;
    let component: LiveDashboardComponent;
    let service: LiveDashboardService

    // Configure Testing Module
    beforeEach(async () => {
        TestBed.configureTestingModule({
            declarations: [LiveDashboardComponent],
            providers: [LiveDashboardService, FormBuilder, MeasurementService],
            schemas: [
                CUSTOM_ELEMENTS_SCHEMA,
                NO_ERRORS_SCHEMA
            ]
        }).compileComponents();
    })

    // Configure component and service(s)
    beforeEach(() => {
        fixture = TestBed.createComponent(LiveDashboardComponent);
        component = fixture.componentInstance;
        fixture.detectChanges(); // triggers Angular change detection
        service = fixture.debugElement.injector.get(LiveDashboardService);
    })

    afterEach(() => {
        fixture.destroy(); // Destroys the fixture and its contents
        component = null; // Reset the component reference
        fixture = null; // Reset the fixture reference
    });

    test('Component should be defined', () => {
        expect(component).toBeDefined();
    })
});

I turns out I had to remove the import statements for BrowserDynamicTestingModule and platformBrowserDynamic as the test environment is already being initialized in the index.ts file.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.