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

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

Comments

@gustavovendramini
Copy link

@gustavovendramini gustavovendramini commented Apr 1, 2020

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 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

@gustavovendramini gustavovendramini commented Apr 2, 2020

@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 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.