如何确保java compareTo返回与Database ORDER BY相同的结果?

时间:2014-12-30 11:17:05

标签: java database

在单元测试中,我验证Db查询的结果,该查询包含" ORDER BY DESC" part和return String values。

要明确:我检查查询是否按预期顺序返回预期结果

SQL查询:

SELECT member.name FROM member ORDER BY member.name DESC

测试结果:

MTH_TESTER_TAXER_W_HLPERS_AFcCmhecUo
MTH_TESTER_TAXER_wCfRUAQuzT

使用java验证结果时,我会这样做:

foreach(String value : values) {
  if (previous != null) {
   assertTrue(value.compareToIgnoreCase(previous) <= 0);
  }  
  previous = value;
}

使用ORDER BY的上述DB结果失败(上例中的降序)。 所以基本上java中的以下内容失败但不在DB中:

assertTrue("MTH_TESTER_TAXER_wCfRUAQuzT".compareToIgnoreCase("MTH_TESTER_TAXER_W_HLPERS_AFcCmhecUo") <= 0)

为什么ORDER BY与Java compareTo自然字符串排序不兼容?

如何使它们兼容?

我在Windowsd 7上使用Postgresql 9.X,默认安装。

4 个答案:

答案 0 :(得分:2)

尝试使用字符串&#39; CASE_INSENSITIVE_ORDER

 String[] str = {"abc", "pqr", "zxt", "Zxy", "xyz"};
 Arrays.sort(str, String.CASE_INSENSITIVE_ORDER.reversed());
 System.out.println(Arrays.toString(str));

答案 1 :(得分:0)

如果您将sql更改为

SELECT member.name FROM member ORDER BY UPPER(member.name) DESC

您的Java代码可能会验证此订单。

或者,如果您将Java代码更改为

foreach(String value : values) {
  if (previous != null) {
   assertTrue(value.compareTo(previous) <= 0);
  }  
  previous = value;
}

它应该验证当前sql执行区分大小写的顺序。

答案 2 :(得分:0)

这里有两种可能的解决方案:

  1. 您根本不依赖ORDER BY。您可以使用它,但在比较之前,您再次在Java中对实际输出进行排序,以确保顺序始终相同。

    如果您只需确保查询的实际排序顺序并不重要,只需确保元素的数量和内容,请使用此方法。

  2. 不是单独比较每个字符串,而是将结果合并为一个多行字符串,然后使用常量字符串执行单个assertEquals()

  3. 第二个解决方案如下:

    String actual = Joiner.on('\n').join(Ordering.natural().sortedCopy(values));
    assertEquals(
         "MTH_TESTER_TAXER_W_HLPERS_AFcCmhecUo\n" +
         "MTH_TESTER_TAXER_wCfRUAQuzT",
         actual
    );
    

    第二个测试会立即检查所有值,让您只需一眼就可以看到哪些值已发生变化,哪些值是意外的,哪些值丢失。

    它还允许您安全地测试数据库返回的结果排序。

答案 3 :(得分:0)

您是否尝试验证数据库查询是否正常工作?如果是这样,那么我首先要确保我知道完全从数据库返回的内容。您的代码中没有任何信息,但我希望您在测试运行之前通过直接SQL或dbUnit之类的方式播种数据。

完成后,您可以对测试中返回的结果进行精确比较。我会避免你目前的测试,因为它没有诊断测试失败时的错误。如果你有这个,你的测试可能是这样的:

List<String> expected = Arrays.asList("MTH_TESTER_TAXER_W_HLPERS_AFcCmhecUo", "MTH_TESTER_TAXER_wCfRUAQuzT");
List<String> actual = myCode.performQuery(); // <-- your method under test goes here
assertThat(expected, contains(actual));

这将确保您返回的集合具有与您指定的顺序相同的相同项目,如果有不同之处,它将告诉您确切的内容。