如何在 JOOQ 中手动创建 RecordN 实例?

How do I create an instance of RecordN manually in JOOQ?

我正在为将数据导入数据库的脚本编写一些测试。脚本的单元测试看起来或多或少像

doAnImport(fileName, databaseToImportInto)
Result<Record2<String, Integer>> results 
    = databaseToImportInto.select(aStringField, anIntegerField)
                          .from(oneTable)
                          .join(anotherTable).on(someField.eq(someOtherField)
                          .fetch();

我现在想做的是 Junit 断言

assertEquals(10, results.getSize());
assertTrue(results.contains(new Record2<String, Integer>(expectedString1, expectedInteger1);
...
assertTrue(results.contains(new Record2<String, Integer>(expectedString10, expectedInteger10);

因为我不想假设结果中有任何特定的顺序。我的问题是 Record2 是一个接口,而 RecordImpl 是不公开可见的。

我能看到的其他选项(将测试查询变成一个视图并为其生成 类 以便有一个 XXXRecord 实现)对我来说并不真正可用 - 这些查询的数量越来越多,并且我不想将我的数据库模式与我的测试用例的特性联系起来。

我想我可以创建我自己的 RecordImpl 子类,但这看起来工作量很大,所以我猜想考虑到库其余部分的优雅(如果你还没有尝试过,你真的应该),这不是 "right thing".

如有任何帮助,我们将不胜感激。

啊。我在查看其他文档时找到了答案。

DSL.row()

将 return RowN 的实现,然后您可以使用它与结果进行比较,方法是调用

Record.valuesRow() 

关于结果中的值。

记录一下,我的测试实用函数现在看起来像这样

public static void looksLike(boolean matchSize, Result<?> results, Row ... theseRows)
{
    if (matchSize)
    {
        assertEquals(results.size(), theseRows.length);
    }

    List<Row> resultsRows = new ArrayList<Row>();
    for (Record r : results)
    {
        resultsRows.add(r.valuesRow());
    }

    for (Row r : theseRows)
    {
        assertTrue(r.toString() + " missing from " + results, resultsRows.contains(r));
    }
}

正如我在问题中所说的那样,确实有一种简单的方法可以做我想做的事。 JOOQ 框中的另一个勾号。

我认为实现此目的的最简单方法是:

assertEquals(new HashSet<>(result1), new HashSet<>(result2));

这将比较两个 Result 对象,忽略记录顺序。这就是创建临时记录的方式:

Record record = DSL.using(...).newRecord(result1.fields());

但确实可能有改进的空间 API。