使用内存数据源进行验收测试不起作用

Acceptance testing with memory datasource doesn't work

我创建了使用内存数据源的控制器验收测试。 在测试开始之前,我试图拥有干净的数据库,并且只通过调用端点添加 1 个用户凭据来登录,因为其余测试需要使用访问令牌进行身份验证访问。

givenUser创建用户记录后,我可以在getUser中获取用户信息。 但是,登录请求找不到凭据。似乎助手和客户端没有共享同一个内存数据源。

我不确定在这种情况下是什么配置设置错误。

src/tests/fixtures/datasources/testdb.datasource.ts

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

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

src/datasources/mongodb.datasource.ts

import {inject} from '@loopback/core';
import {juggler} from '@loopback/repository';
import * as config from './mongodb.datasource.json';

export class MongodbDataSource extends juggler.DataSource {
  static dataSourceName = 'mongodb';

  constructor(
    @inject('datasources.config.mongodb', {optional: true})
    dsConfig: object = config,
  ) {
    super(dsConfig);
  }
}

user.controller.acceptance.ts

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

describe('UserController', () => {
  let app: ApiApplication;
  let client: supertest.SuperTest<supertest.Test>;;
  let jwtToken: string;

  before('setupApplication', async () => {
    ({app, client} = await setupApplication());
  });
  before(givenEmptyDatabase);
  before(givenUser);
  before(getUser);
  before(async () => {
    const response = await client
      .post('/login')
      .send({username: 'user1', password: 'password'});
    jwtToken = response.body.token;
  });

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

  it('invokes GET /info without authentication', async () => {
    const expectedError = {
      error: {
        statusCode: 401,
        name: 'UnauthorizedError',
        message: 'Unauthorized'
      }
    };
    const res = await client.get('/user/info').expect(401);
    expect(res.body).to.containEql(expectedError);
  });

测试-help.ts

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

export async function setupApplication(): Promise<AppWithClient> {

  const app = new ApiApplication();
  await app.bind('datasources.config.mongodb').to({
    name: 'mongodb',
    connector: 'memory',
    debug: true,
  });

  await app.boot();
  await app.start();

  const client = createRestAppClient(app);

  return {app, client};
}

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

database.helper.ts

import { UserRepository } from '../../repositories';
import { User } from '../../models';
import { testdb } from '../fixtures/datasources/testdb.datasource';

export async function givenEmptyDatabase() {
  let userRepo: UserRepository;

  userRepo = new UserRepository(testdb);

  userRepo.deleteAll();
}

export async function givenUser() {
  let userRepo = new UserRepository(testdb);
  const user = {
    username: 'user1',
    password: 'password',
    created_at: new Date('2019-08-08'),
    updated_at: new Date('2019-08-08'),
  }
  await userRepo.create(operator);
}

export async function getUser() {
  let userRepo = new UserRepository(testdb);
  const users = await userRepo.find();
  console.log(users);
}

It seems that the helpers and client are not sharing the same memory datasource.

完全正确。

重要的是要认识到您可以使用同一个连接器拥有多个数据源,例如您可以 logDb 使用一个 MongoDB 服务器并 userDb 连接到另一个。这同样适用于 memory 数据源,您可以使用 memory 连接器拥有多个数据源,每个实例都有自己的 space 数据。

由于您已经在测试中更改了主 mongodb 数据源的配置,我的建议是在设置初始测试数据时使用修改后的数据源。

database.helper.ts中:

export async function givenEmptyDatabase(db) {
  let userRepo: UserRepository;

  userRepo = new UserRepository(db);

  userRepo.deleteAll();
}

export async function givenUser(db) {
  // ...
}
// and so on

在你的测试中:

before(async () => {
 const db = await app.get<juggler.DataSource>('datasources.config.mongodb');
 await givenEmptyDatabase(db);
});

就个人而言,我强烈建议您在测试中使用与在生产中使用的数据库相同的数据库。 memory 数据库的行为与 MongoDB 不同。某些操作在 memory 中存储数据时可能会通过,但在使用 MongoDB 时会失败。

您可以在 LoopBack 的 "Best Practice" 指南中了解有关测试的更多信息:Testing your application