Search code examples
loopbackjs

Loopback 4 - Connect to test database on Npm Test


I want to run an in-memory database for my tests, but I'm unable to make my application connect to it when I run npm test.

When I run npm test i get:

Connection fails: Error: ER_ACCESS_DENIED_ERROR: Access denied for user ''@'172.21.0.1' (using password: NO)

This is happening because I'm not setting any env variables on npm test, but I don't want to use MySQL on my tests and just an in-memory database, here what I have.

testdb.datasources.ts

import {juggler} from '@loopback/repository';

export const testdb: juggler.DataSource = new juggler.DataSource({
  name: 'testdb',
  connector: 'memory',
});

country.controller.acceptance.ts

import {Client, expect} from '@loopback/testlab';
import {MyApplication} from '../..';
import {setupApplication} from './test-helper';
import {givenEmptyDatabase} from '../helpers/database.helpers';

describe('Country Controller', () => {
  let app: MyApplication;
  let client: Client;

  before('setupApllication', async () => {
    ({app, client} = await setupApplication());
  });

  before(givenEmptyDatabase);
  // before(givenRunningApp);

  after(async () => {
    await app.stop();
  });

  it('Should count 0 countries', async () => {
    const res = await client.get('/countries/count').expect(200);

    //assertations
    expect(res.body.count).to.equal(0);
  });
});

test-helper.ts

import {MyApplication} from '../..';
import {
  createRestAppClient,
  givenHttpServerConfig,
  Client,
} from '@loopback/testlab';
import {testdb} from '../fixtures/datasources/testdb.datasource';

export async function setupApplication(): Promise<AppWithClient> {
  const app = new MyApplication({
    rest: givenHttpServerConfig({host: 'localhost'}),
  });

  app.dataSource(testdb); // <--- Hoped this would do the job 
  await app.boot();
  await app.start();

  const client = createRestAppClient(app);

  return {app, client};
}

export interface AppWithClient {
  app: MyApplication;
  client: Client;
}

The Country controller is just a standard controller create using lb4 controller.

  @get('/countries/count', {
    responses: {
      '200': {
        description: 'country model count',
        content: {'application/json': {schema: countschema}},
      },
    },
  })
  async count(
    @param.query.object('where', getwhereschemafor(country)) where?: where,
  ): promise<count> {
    return await this.countryrepository.count(where);
  }

Any ideas on whats going wrong?


Solution

  • i Found this way that works for me

    Change this:

    app.dataSource(testdb);
    

    To this:

    app.bind('datasource.config.db').to({
       name: 'db',
       connector: 'memory'
    });
    

    You are just changing the configurations of datasource to use a local database but is still the same datasource!

    make sure that the string of bind is the same used in your main datasource!