【问题标题】:Acceptance testing with memory datasource doesn't work内存数据源的验收测试不起作用
【发布时间】:2020-01-18 22:15:56
【问题描述】:

我创建了使用内存数据源的控制器验收测试。 在测试开始之前,我试图拥有干净的数据库,并且只通过调用端点添加 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);
  });

test-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);
}

【问题讨论】:

    标签: debugging testing datasource loopback acceptance-testing


    【解决方案1】:

    帮助者和客户端似乎没有共享相同的内存数据源。

    没错。

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

    由于您已经在测试中更改了主 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 的“最佳实践”指南中了解有关测试的更多信息:Testing your application

    【讨论】:

      猜你喜欢
      • 2017-01-14
      • 1970-01-01
      • 2015-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-30
      • 1970-01-01
      相关资源
      最近更新 更多