Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[QUESTION] Integration with Jest - Schema hasn't been registered for model #793

Closed
gustavovendramini opened this issue Apr 1, 2020 · 3 comments
Assignees

Comments

@gustavovendramini
Copy link

How to load Ts.ED schemas outside the server context?

I'm writing tests with Jest and I`m receiving this:

● Test suite failed to run
 
    MissingSchemaError: Schema hasn't been registered for model "Spirit".
    Use mongoose.model(name, schema)

I have tried with const SpiritModel = mongoose.model('Spirit') as MongooseModel<Spirit> but no sucess.

I'm using Typescript 3.8.3, Ts.ED 5.44, Jest/ts-jest 25.x and express 4.17

mytest.test.ts

import "@tsed/mongoose";
import { MongooseModel } from "@tsed/mongoose";
import * as mongoose from 'mongoose';
import { Spirit } from '../src/models/Spirit';

const SpiritModel = mongoose.model('Spirit') as MongooseModel<Spirit>

test('get a wild spirit', async () => {
  expect.assertions(1);
  const spirit = await SpiritModel.findOne({ wild: true, power: 1, state: '' }).exec();
  expect(spirit?.wild).toBe(true);
})

package.json

"scripts": {
    "test": "TS_TEST=true jest"
  },

jest.config.js

module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  setupFiles: ['dotenv/config'],
  roots: ['tests'],

  globals: {
    'ts-jest': {
      tsConfig: 'tsconfig.json'
    }
  },
  verbose: true,
  collectCoverage: true,
  moduleFileExtensions: ['ts', 'js', 'json'],
  testMatch: ['**/tests/**/*.test.ts'],
  testEnvironment: 'node',
  testPathIgnorePatterns: ['<rootDir>/node_modules/', '<rootDir>/out/'],
  modulePathIgnorePatterns: ['<rootDir>/node_modules/', '<rootDir>/out/'],
  coverageDirectory: 'tests/result',
  collectCoverageFrom: [
    'src/controllers/**/*.ts',
    'src/middlewares/**/*.ts',
    'src/services/**/*.ts',
    '!**/*.d.ts'
  ]
};

@Romakita
Copy link
Collaborator

Romakita commented Apr 1, 2020

Hello @gustavovendramini
Have your looked this page : https://tsed.io/tutorials/mongoose.html#testing-model

It should solve your problem :)

See you

@gustavovendramini
Copy link
Author

@Romakita That not worked for me ...

But I followed @striquer tip and it worked

import { createSchema, createModel } from "@tsed/mongoose";
import { Character } from "../src/models/Character";
import { Document } from "mongoose";
import { MongooseService } from "../src/services/MongooseService";
import { States } from "../src/interfaces/States";

const characterSchema = createSchema(Character, { schemaOptions: { _id: false } });
const CharacterModel = createModel<Character>(Character, characterSchema, 'Character', 'characters');

beforeAll(() => {
    return MongooseService.connect(process.env.MONGO_CONNECTION_URL, {
        useNewUrlParser: true,
        useCreateIndex: true,
        useFindAndModify: false,
        useUnifiedTopology: true,
        poolSize: 40
    });
});

afterAll(() => {
    return MongooseService.get().connection.close()
});

test('Character state its NORMAL', async () => {
    expect.assertions(1);
    const character = await CharacterModel.findOne({ name: 'Grace' }).exec() as Character & Document;
    expect(character.state).toBe(States.NORMAL);
})

@Romakita
Copy link
Collaborator

Romakita commented Apr 2, 2020

Ha ook :)
But you create a connection on a physical mongo db.
It strange. Because the TestMongooseContext is here to solve this problem, and I have some unit test on mongoose model which is works.

import {TestMongooseContext} from "@tsed/testing-mongoose";
import { MongooseModel } from "@tsed/mongoose";
import { Spirit } from '../src/models/Spirit';

describe("SpiritModel", () => {
  beforeEach(TestMongooseContext.create);
  afterEach(TestMongooseContext.reset);

  it("get a wild spirit", TestMongooseContext.inject([SpiritModel], async (model: MongooseModel<SpiritModel>) => {
      // GIVEN - Create and add data to the mocked database
      const spirit = new SpiritModel({ wild: true, power: 1, state: '' }); 
      await user.save();

      // THEN - Get the data in the mocked database
      const result = await SpiritModel.findOne({ wild: true, power: 1, state: '' }).exec();
      expect(result?.wild).toBe(true);
  }));
});

I think when you have tested the solution given document, you've missed to populate the mocked database befare run the findOne() method :)

See you
Romain

@Romakita Romakita closed this as completed Oct 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants