sequelize-typescript icon indicating copy to clipboard operation
sequelize-typescript copied to clipboard

Example with using sequelize typescript to mock database

Open josecolella opened this issue 4 years ago • 5 comments

Hello @RobinBuschmann ,

First of all thank you for such a great project. One question I did have a question on is how to use sequelize-typescript to mock the database and run queries against mocked data

josecolella avatar Oct 20 '20 18:10 josecolella

+1

goalia avatar Oct 21 '20 15:10 goalia

I tried the following:

{
          provide: SOME_SYMBOL,
          useFactory: async () => {
            const sequelize = new Sequelize({
              validateOnly: true
            });
            sequelize.addModels([someModel, someModel2]);
            return sequelize;
          }
        }

when I try to create an instance of a model to mock the data that is in database, I receive the following:

this.lib.Database is not a constructor

@RobinBuschmann any ideas here? I would love to not have to download another lib for tests only

josecolella avatar Nov 05 '20 16:11 josecolella

I have the same issue, and even if I leave all the other options the same, adding validateOnly: true leads to this.lib.Database is not a constructor.

werkshy avatar Mar 10 '21 21:03 werkshy

I have the same problem:

import { getModelToken } from '@nestjs/sequelize';
import { Test } from '@nestjs/testing';
import { Sequelize } from 'sequelize-typescript';

import { Role } from './role.model';
import { RolesService } from './roles.service';

const sequelize = new Sequelize({ validateOnly: true });
sequelize.addModels([Role]);

const testRole = new Role({
  name: 'owner',
});

describe('RolesService', () => {
  let rolesService: RolesService;

  beforeEach(async () => {
    const serviceModule = await Test.createTestingModule({
      providers: [
        RolesService,
        {
          provide: getModelToken(Role),
          useValue: {
            findAll: jest.fn(() => [testRole]),
          },
        },
      ],
    }).compile();

    rolesService = serviceModule.get(RolesService);
  });

  it('should get all the roles', async () => {
    expect(await rolesService.getRoles()).toEqual([testRole]);
  });
});

This returns this.lib.Database is not a constructor.

Edit: The reason why this is not working can be found in my service:

@Injectable()
export class RolesService {
  async getRoles(): Promise<Role[]> {
    return await Role.findAll();
  }
}

If I inject the repository like this

@Injectable()
export class RolesService {
  constructor(
    @InjectModel(Role)
    private readonly rolesRepository: Repository<Role>,
  ) {}

  async getRoles(): Promise<Role[]> {
    return await this.rolesRepository.findAll();
  }
}

it works. We somehow have to tell the model in the service to use the validateOnly: true instance of sequelize.

alexvoedi avatar Mar 23 '21 08:03 alexvoedi

Hey, just came here to say that i can't find a solution, so i've literally used a fake sqlite database at the unit tests and mock ALL results. I Know that it isn't the best solution, but i've searched a lot and can't find anything. So, the code is:

  let model: typeof  YourModel;
beforeEach(async () => {
    const modRef = await Test.createTestingModule({
      imports: [
        SequelizeModule.forRoot({
          dialect: 'sqlite',
          database: ':memory:',
          autoLoadModels: true,
          synchronize: true,
          logging: false,
          models: [YourModel]
        })
      ],
      providers: [
        YourService,
        {
          provide: getModelToken( YourModel ),
          useValue: {
            findAll: jest.fn(),
            findOne: jest.fn(),
            create: jest.fn(),
            update: jest.fn()
          }
        }
      ]
    }).compile();

    service = modRef.get(YourService);
    model = modRef.get<typeof YourModel>(getModelToken(YourModel));
  });```

XamuAvila avatar Jul 08 '22 14:07 XamuAvila