0

I'm trying to set up testing using Jest for a NestJS service. When I run jest, a ReferenceError is thrown that says "common_1 is not defined" for both the service and controller tests. I think this is related to an import from @nestjs/common:

import { Injectable } from '@nestjs/common';

expected result: tests run without error thrown

actual result:

 FAIL  src/regmol/regmol-oligos/regmol-oligos.service.spec.ts
  ● Test suite failed to run

    ReferenceError: common_1 is not defined

      10 |
      11 |
    > 12 | @Injectable()
         |  ^
      13 | export class RegmolOligosService {
      14 |
      15 |   

      at Object.<anonymous> (regmol/regmol-oligos/regmol-oligos.service.ts:12:2)
      at Object.<anonymous> (regmol/regmol-oligos/regmol-oligos.service.spec.ts:3:1)

 FAIL  src/regmol/regmol-oligos/regmol-oligos.controller.spec.ts
  ● Test suite failed to run

    ReferenceError: common_1 is not defined

      10 |
      11 |
    > 12 | @Injectable()
         |  ^
      13 | export class RegmolOligosService {
      14 |
      15 |   

      at Object.<anonymous> (regmol/regmol-oligos/regmol-oligos.service.ts:12:2)
      at Object.<anonymous> (regmol/regmol-oligos/regmol-oligos.controller.spec.ts:3:1)

regmol-oligos-controller.ts

import { Controller, Get, Param, Post, Body } from '@nestjs/common';
import { RegmolOligosService } from './regmol-oligos.service';
import { CheckHelmUniquenessDto } from '../dto/check-helm-uniqueness.dto';
import { BatchCheckHelmUniquenessDto } from '../dto/batch-check-helm-uniqueness.dto';

@Controller('regmol-oligos')
export class RegmolOligosController {

  constructor(private regmolOligosService: RegmolOligosService) {}

  @Post('/helm/check-uniqueness')
  async checkHelmUniqueness(@Body() body: CheckHelmUniquenessDto): Promise<any> {
    const helm = body['helm'];
    return this.regmolOligosService.checkHelmUniqueness(helm);
  }

  @Post('/helm/batch-check-uniqueness')
  async batchCheckHelmUniqueness(@Body() body: BatchCheckHelmUniquenessDto): Promise<any> {
    return this.regmolOligosService.batchCheckHelmUniqueness(body);
  }
}

regmol-oligos-controller.spec.ts

import { Test, TestingModule } from '@nestjs/testing';
import { RegmolOligosController } from './regmol-oligos.controller';
import { RegmolOligosService } from './regmol-oligos.service';
import { HttpModule } from '@nestjs/axios';
import { of } from 'rxjs';

describe('RegmolOligosController', () => {
  let regmolOligosController: RegmolOligosController;
  let regmolOligosService: RegmolOligosService;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      imports: [HttpModule],
      controllers: [RegmolOligosController],
      providers: [RegmolOligosService]
    }).compile();

    regmolOligosController = module.get<RegmolOligosController>(RegmolOligosController);
    regmolOligosService = module.get<RegmolOligosService>(RegmolOligosService);
    
  });

it('should be defined', () => {
    expect(regmolOligosController).toBeDefined();
  });

  it('should validate uniqueness of single helm string', async() => {
    // this tests the controller's responsibility only by mocking the implementation of the service function checkHelmUniqueness()
    const helm: string = "RNA1{[moe](G)[sp].[moe]([m5C])[sp].[moe]([m5C])[sp].[moe](T)[sp].[moe]([m5C])[sp].d(A)[sp].d(G)[sp].d(T)[sp].d([m5C])[sp].d(T)[sp].d(G)[sp].d([m5C])[sp].d(T)[sp].d(T)[sp].d([m5C])[sp].[moe](G)[sp].[moe]([m5C])[sp].[moe](A)[sp].[moe]([m5C])[sp].[moe]([m5C])}$$$$";
    const result = {
      success: true,
      helm,
      unique: false,
      predecessorRegmolId: "IONIS-HELM200000183731"
    };
    jest.spyOn(regmolOligosService, 'checkHelmUniqueness').mockImplementation(async () => result);
    expect(await regmolOligosController.checkHelmUniqueness({ helm })).toBe(result);
  })
});

regmol-oligo-service.ts

import { Injectable } from '@nestjs/common';
import { CheckHelmUniquenessDto } from '../dto/check-helm-uniqueness.dto';
// import * as FormData from 'form-data';
import FormData from 'form-data';
import { HttpService } from '@nestjs/axios';
import { map } from 'rxjs/operators';
import { forkJoin } from 'rxjs';
import { BatchCheckHelmUniquenessDto } from '../dto/batch-check-helm-uniqueness.dto';
import { Observable } from 'rxjs';


@Injectable()
export class RegmolOligosService {

  
  constructor(
    private httpService: HttpService,
    ) {}
    
  structureCheckParentUrl = `${process.env.REGMOL_URL}/ajax.ashx?wrapper=json&cmd=structure.checkparent`;
  async checkHelmUniqueness(helm: string) {

    const form = new FormData();
    form.append('sketch', helm);
    form.append('compoundType', 'oligonucleotide');

    const headers = {
      ...form.getHeaders(),
      'MolEngineApiKey': process.env.MOL_ENGINE_API_KEY
    };

    let response$ = this.httpService.post(this.structureCheckParentUrl, form, { headers })
              .pipe(map((response: any) => response.data));
    let response = await response$.toPromise();
    return response;
    
  }

  async batchCheckHelmUniqueness(body: BatchCheckHelmUniquenessDto) {
    const oligos = body['oligos'];

    const oligosData = {};
    oligos.forEach(oligo => oligosData[oligo.oligoId] = this.checkHelmUniqueness(oligo.helm))

    let response$ = forkJoin(oligosData).pipe(map(oligosData => {
      const response = {};

      Object.entries(oligosData).forEach(([oligoId,v]: any) => {
        response[oligoId] = {};
        response[oligoId].success = v.succeed;

        if (v.succeed) {
          let oligo = oligos.find(oligo => oligo.oligoId === +oligoId);
          response[oligoId].helm = oligo.helm;
          if (v['ret']['compoundid'] !== undefined) {
            response[oligoId].unique = v.ret.compoundid === "NEW";
            response[oligoId].predecessorRegmolId = v.ret.compoundid;
          }
        }
      })
      return response;
    }));

    return response$.toPromise();
  }

}

regmol-oligos.service.spec.ts

import { HttpModule } from '@nestjs/axios';
import { Test, TestingModule } from '@nestjs/testing';
import { RegmolOligosService } from './regmol-oligos.service';

describe('RegmolOligosService', () => {
  let service: RegmolOligosService;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      imports: [HttpModule],
      providers: [RegmolOligosService],
    }).compile();

    service = module.get<RegmolOligosService>(RegmolOligosService);
  });

it('should be defined', () => {
    expect(service).toBeDefined();
  });

  it('should validate uniqueness of single helm string', async() => {
    // this tests the controller's responsibility only by mocking the implementation of the service function checkHelmUniqueness()
    const helm: string = "RNA1{[moe](G)[sp].[moe]([m5C])[sp].[moe]([m5C])[sp].[moe](T)[sp].[moe]([m5C])[sp].d(A)[sp].d(G)[sp].d(T)[sp].d([m5C])[sp].d(T)[sp].d(G)[sp].d([m5C])[sp].d(T)[sp].d(T)[sp].d([m5C])[sp].[moe](G)[sp].[moe]([m5C])[sp].[moe](A)[sp].[moe]([m5C])[sp].[moe]([m5C])}$$$$";
    const result = {
      success: true,
      helm,
      unique: false,
      predecessorRegmolId: "IONIS-HELM200000183731"
    };
    
    expect(await service.checkHelmUniqueness(helm)).toBe(result);
  })


});

package.json

{
  "name": "oligo-registration-service",
  "version": "0.0.1",
  "description": "",
  "author": "",
  "private": true,
  "license": "UNLICENSED",
  "scripts": {
    "prebuild": "rimraf dist",
    "build": "nest build",
    "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
    "start": "nest start",
    "start:dev": "nest start --watch",
    "start:debug": "nest start --debug --watch",
    "start:prod": "node dist/main",
    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "test:e2e": "jest --config ./test/jest-e2e.json",
    "test:regmol-oligos": "jest regmol-oligos"
  },
  "dependencies": {
    "@nestjs/axios": "^0.0.7",
    "@nestjs/common": "^8.0.0",
    "@nestjs/config": "^1.1.6",
    "@nestjs/core": "^8.0.0",
    "@nestjs/mapped-types": "*",
    "@nestjs/passport": "^8.2.1",
    "@nestjs/platform-express": "^8.0.0",
    "@nestjs/terminus": "^8.0.6",
    "@nestjs/typeorm": "^8.0.3",
    "@types/date-and-time": "^0.13.0",
    "class-transformer": "^0.5.1",
    "class-validator": "^0.13.2",
    "dotenv": "^12.0.4",
    "express": "^4.17.2",
    "form-data": "^4.0.0",
    "joi": "^17.6.0",
    "knex": "^0.95.15",
    "lodash": "^4.17.21",
    "moment": "^2.29.4",
    "nestjs-knex": "^2.0.0",
    "oracledb": "^5.4.0",
    "reflect-metadata": "^0.1.13",
    "rimraf": "^3.0.2",
    "rxjs": "^7.2.0",
    "swagger-ui-express": "^4.3.0",
    "typeorm": "^0.2.41"
  },
  "devDependencies": {
    "@nestjs/cli": "^9.1.4",
    "@nestjs/schematics": "^8.0.0",
    "@nestjs/testing": "^8.0.0",
    "@types/express": "^4.17.13",
    "@types/jest": "27.4.1",
    "@types/lodash": "4.14.121",
    "@types/node": "^16.0.0",
    "@types/supertest": "^2.0.11",
    "@typescript-eslint/eslint-plugin": "^5.0.0",
    "@typescript-eslint/parser": "^5.0.0",
    "eslint": "^8.0.1",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-prettier": "^4.0.0",
    "jest": "^27.5.1",
    "prettier": "^2.3.2",
    "source-map-support": "^0.5.20",
    "supertest": "^6.1.3",
    "ts-jest": "^27.0.3",
    "ts-loader": "^9.2.3",
    "ts-node": "^10.7.0",
    "tsconfig-paths": "^3.10.1",
    "typescript": "^4.3.5"
  },
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "ts"
    ],
    "rootDir": "src",
    "testRegex": ".*\\.spec\\.ts$",
    "transform": {
      "^.+\\.(t|j)s$": "ts-jest"
    },
    "collectCoverageFrom": [
      "**/*.(t|j)s"
    ],
    "coverageDirectory": "../coverage",
    "testEnvironment": "node"
  }
}
Pand0
  • 11
  • 4
  • Your imports look fine. So does your jest config. Is this happening locally or in CI or something else? I don't immediately see anything that would cause this issue – Jay McDoniel Oct 16 '22 at 03:06
  • @JayMcDoniel I'm just trying to run this locally for now. – Pand0 Oct 16 '22 at 03:14
  • Hmm, weird. Is there any chance you can share your project? I haven't ran into something like this before – Jay McDoniel Oct 16 '22 at 03:19
  • I don't think I can share the whole project without clearing that with my employer first. I may need to start over with a new repo and try again. – Pand0 Oct 16 '22 at 03:29

0 Answers0