如何使用PostgreSQL对Redstone进行单元测试?

时间:2015-05-06 17:06:23

标签: postgresql unit-testing dart

我正在尝试使用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

我想我回答了我的问题:)

0 个答案:

没有答案