我使用内存数据源创建了控制器的验收测试。 在测试开始之前,我试图拥有干净的数据库,并且仅添加1个用户凭据才能通过调用端点登录,因为其余测试需要使用访问令牌进行经过身份验证的访问。
从getUser
创建用户记录后,我可以在givenUser
中获取用户信息。
但是,登录请求找不到凭据。助手和客户端似乎没有共享相同的内存数据源。
我不确定在这种情况下哪种配置设置是错误的。
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);
}
答案 0 :(得分:1)
助手和客户端似乎没有共享相同的内存数据源。
完全正确。
重要的是要意识到,可以使用同一连接器拥有多个数据源,例如,可以使用一台MongoDB服务器使用一个logDb
,而使用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