我正在尝试使用PostgreSQL扩展为Redstone微框架进行单元测试。没有pgsql请求的简单路由测试工作正常。但是当Route包含pgsql请求时,测试失败,因为resp.statusCode = 500。当我直接从test调用带有pgsql请求的应用程序函数时,它会返回错误,因为app.request为null。这是代码示例:
//--------------------------------------------------------
// Redstone application
library rs_app;
import 'dart:async';
import 'package:redstone/server.dart' as app;
import 'package:redstone_mapper/plugin.dart';
import 'package:redstone_mapper_pg/manager.dart';
Future startServer() {
var uri = "postgres://127.0.0.1:5432/testdb";
var dbManager = new PostgreSqlManager(uri, min: 1, max: 3);
app.addPlugin(getMapperPlugin(dbManager));
app.setupConsoleLog();
return app.start(address: '127.0.0.1', port: 8100);
}
PostgreSql get pgsql => app.request.attributes.dbConn;
@app.Route("/simple")
simpleAnswer() => "Hello, world!";
@app.Route("/complex")
complexAnswer() => getMaxId();
Future getMaxId() {
return pgsql.query("select max(id) as id from t_test", String)
.then((id) {
return new Future.value(id[0]['id']);
});
}
//--------------------------------------------------------
// Unit tests
library rs_app_test;
import 'package:rs_app/rs_app.dart' as rs_app;
import 'package:redstone/server.dart' as app;
import 'package:redstone/mocks.dart';
import 'package:unittest/unittest.dart';
main() => makeTests();
void makeTests() {
setUp(() => app.setUp([#rs_app]));
tearDown(() => app.tearDown());
test('simple - PASS', () {
var req = new MockRequest('/simple');
return app.dispatch(req).then((resp) {
expect(resp.statusCode, equals(200));
expect(resp.mockContent, equals("Hello, world!"));
});
});
test('complex - FAIL', () {
var req = new MockRequest('/complex');
return app.dispatch(req).then((resp) {
expect(resp.statusCode, equals(200));
expect(resp.mockContent, equals("0297"));
});
});
test('direct - ERROR', () {
return rs_app.getMaxId().then((id) {
expect(id, equals("0297"));
});
});
}
我知道dbManager没有正确初始化,但我必须如何初始化它?
在Günter的建议之后,我进行了实验并找到了一些测试解决方案:
void makeTests() async {
//setUp(() => app.setUp([#rs_app])); not needed
//tearDown(() => app.tearDown()); closes all (and db-connection!) after each test
await rs_app.startServer();
test('simple - PASS', () { ... });
test('complex - PASS NOW', () { ... });
test('direct - STILL ERROR', () { ... });
}
直接测试返回错误“null对象没有getter'属性'”,即getMaxId()中的app.request为null。我认为原因是直接测试中不存在http请求 - 以及app.request。需要在getMaxId()中更改对PostgreSQL连接的访问。
Redstone仅在http请求处理期间提供对DB连接的访问。如果我们想在没有http请求上下文的情况下测试一些DB函数,我们必须关注我们测试中的DB连接:
//--------------------------------------------------------
// Redstone application
// needed imports
PostgreSqlManager dbManager;
Future startServer() {
var uri = "postgres://127.0.0.1:5432/testdb";
dbManager = new PostgreSqlManager(uri, min: 1, max: 3);
app.addPlugin(getMapperPlugin(dbManager));
app.setupConsoleLog();
return app.start(address: '127.0.0.1', port: 8100);
}
// skip to getMaxId()
Future getMaxId([PostgreSql test_pgsql]) {
var _pgsql = app.request == null ? test_pgsql : pgsql;
return _pgsql.query("select max(id) as id from t_test", String)
.then((id) {
return new Future.value(id[0]['id']);
});
}
//--------------------------------------------------------
// Unit tests
// skip to direct test
test('direct - PASS NOW', () async {
var pgsql = await rs_app.dbManager.getConnection();
return rs_app.getMaxId(pgsql).then((id) {
rs_app.dbManager.closeConnection(pgsql);
expect(id, equals("0297"));
});
});
// skip other
我想我回答了我的问题:)