代码之家  ›  专栏  ›  技术社区  ›  Jozef Morvay

如何让jOOQ在单元测试期间使用测试表?

  •  1
  • Jozef Morvay  · 技术社区  · 6 年前

    我正在努力找出如何对我的持久性级别方法进行单元测试。对于生产,我使用postgres,我让jOOQ从我的DB模式生成Java类。为了进行测试,我配置了内存中的HSQLDB,并包含了一个模式。用于spring的sql文件创建一个与生产数据库中的表完全匹配的表,每个配置在单独的应用程序中。src或test中的yaml文件。

    现在问题来了。我的持久性层有一些方法,它们直接引用由jOOQ生成的表类,这显然是因为只有该类才有与各个列对应的成员字段。例如:

    private Data DATA = Tables.DATA;
    
    public Timestamp findLatestNonRealtimeClose(String ticker) {
        return (Timestamp) jooq
                .select(max(DATA.DATE))
                .from(DATA)
                .where(DATA.TICKER.eq(ticker))
                .and(DATA.REALTIMECLOSE.eq(Boolean.FALSE))
                .fetch()
                .getValue(0, 0);
    }
    

    该方法只返回给定股票行情器的最新现有日期条目。编写测试时,此方法仍将转到实际的生产数据库,而不是测试数据库。我不能将该表作为存在于jOOQ中的多态参数类型表传递,因为这样我就必须将其转换为表。用于访问列的数据。如果我想使用测试数据库,我甚至不知道将其转换为什么类型,因为HSQLDB表没有运行时Java表示,即使我有,该方法也不知道它是否作为测试的一部分运行。如何重写该方法以考虑测试或生产运行?

    在里面 an article LukasEder写的,据说你不应该对DB代码进行单元测试,但我仍然想这样做。

    2 回复  |  直到 6 年前
        1
  •  4
  •   Lukas Eder    6 年前

    更换jOOQ Configuration 针对您的测试环境

    我不知道您为什么认为jOOQ表引用是这里的问题。您应该能够对任何类型的数据库运行完全相同的jOOQ查询,而无需付出太多努力。唯一的区别应该是如何配置 jooq 实例(即 DSLContext 及其 配置 ):

    单元测试与集成测试

    在Lukas Eder撰写的一篇文章中,有人说您不应该对DB代码进行单元测试,但我仍然愿意这样做。

    你误解了我所说的“单元测试”,以及我所说的“集成测试”(你正在做的)。在我看来,后者很好。当然,我总是建议您针对生产数据库产品(例如PostgreSQL,例如Docker)对应用程序进行集成测试,但如果有充分的理由不这样做,那么HSQLDB可能就足够了。

    单元测试(根据我的定义)将在任何级别上用模拟替换数据库,包括:

    我的文章中的批评指出,在某种程度上,模拟数据库等同于实现数据库,所以为什么不直接使用现成的数据库进行集成测试呢。

        2
  •  1
  •   daniu    6 年前

    你可以模拟整个呼叫链。。。

    when(jooq.select()).thenReturn(whereMock); 
    when(whereMock.from(DATA)).thenReturn(fromMock);
    

    等等然后验证所有调用是否正确。